You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native类组件转函数组件遇阻:useEffect替代componentDidUpdate存疑

问题

将React Native日历应用的类组件改写为函数组件后,其他功能正常,但useEffect替代componentDidUpdate的逻辑未实现原效果,不清楚需要配置哪些依赖来达成原有功能。

旧类组件代码

export default class DaysInMonth extends React.PureComponent{

state = {
    lastCalendarDayIndex: 0, 
    currentCalendarDayIndex: 0,
}

changeCurrentCalendarDayIndex = (index) => {
    this.setState({
        currentCalendarDayIndex: index
    })
}

componentDidUpdate(prevProps, prevState){
    if(this.state.currentCalendarDayIndex !== prevState.currentCalendarDayIndex){
        this.setState({
            lastCalendarDayIndex: prevState.currentCalendarDayIndex
        })
    }
}

render(){
    return(
        <>
            {
                this.props.row_days_array.map((rowData, index) => (
                    <CalendarRow 
                        key = {'calendar row ' + index}
                        rowData = {rowData}

                        lastCalendarDayIndex = {this.state.lastCalendarDayIndex}
                        changeCurrentCalendarDayIndex = {this.changeCurrentCalendarDayIndex}
                        month_index = {this.props.month_index}
                        current_month_index = {this.props.current_month_index}
                        chooseDifferentMonth = {this.props.chooseDifferentMonth}
                    />
                ))
            }
        </>
    )
}
}

新函数组件代码

export default function DaysInMonth({row_days_array, month_index, current_month_index, chooseDifferentMonth}) {
 const [lastCalendarDayIndex, setLastCalendarDayIndex] = useState(0)
 const [currentCalendarDayIndex, setCurrentCalendarDayIndex] = useState(0)

 const changeCurrentCalendarDayIndex = (index) => {
    setCurrentCalendarDayIndex(index)
}

useEffect(() => {
    if(currentCalendarDayIndex !== currentCalendarDayIndex){
        setLastCalendarDayIndex(currentCalendarDayIndex)
    }

  },[]);

  return (
    <>
        {row_days_array.map((rowData, index) => (
            <CalendarRow 
                key = {'calendar row ' + index}
                rowData = {rowData}

                lastCalendarDayIndex = {lastCalendarDayIndex}
                changeCurrentCalendarDayIndex = {changeCurrentCalendarDayIndex}

                month_index = {month_index}
                current_month_index = {current_month_index}
                chooseDifferentMonth = {chooseDifferentMonth}
            />
        ))}
    </>
  )
}

问题分析与解决方案

你的新代码存在两个关键错误:

  • 条件判断逻辑失效:currentCalendarDayIndex !== currentCalendarDayIndex永远为false,这个判断不会触发任何更新操作。
  • useEffect依赖数组错误:空数组意味着effect仅在组件挂载时执行一次,不会监听currentCalendarDayIndex的变化,无法替代componentDidUpdate的监听逻辑。

要还原原类组件的效果,需要用useRef保存currentCalendarDayIndex的上一次值,再通过useEffect监听其变化:

export default function DaysInMonth({row_days_array, month_index, current_month_index, chooseDifferentMonth}) {
 const [lastCalendarDayIndex, setLastCalendarDayIndex] = useState(0)
 const [currentCalendarDayIndex, setCurrentCalendarDayIndex] = useState(0)
 // 用useRef存储上一次的currentCalendarDayIndex值
 const prevCurrentIndexRef = useRef(currentCalendarDayIndex)

 const changeCurrentCalendarDayIndex = (index) => {
    setCurrentCalendarDayIndex(index)
}

useEffect(() => {
    // 当currentCalendarDayIndex变化时,将last设为更新前的旧值
    if (currentCalendarDayIndex !== prevCurrentIndexRef.current) {
        setLastCalendarDayIndex(prevCurrentIndexRef.current)
        // 更新ref为当前值,供下次对比使用
        prevCurrentIndexRef.current = currentCalendarDayIndex
    }
  }, [currentCalendarDayIndex]); // 依赖数组添加currentCalendarDayIndex,监听其变化

  return (
    <>
        {row_days_array.map((rowData, index) => (
            <CalendarRow 
                key={'calendar row ' + index}
                rowData={rowData}
                lastCalendarDayIndex={lastCalendarDayIndex}
                changeCurrentCalendarDayIndex={changeCurrentCalendarDayIndex}
                month_index={month_index}
                current_month_index={current_month_index}
                chooseDifferentMonth={chooseDifferentMonth}
            />
        ))}
    </>
  )
}

逻辑说明

  • 原类组件中componentDidUpdate的prevState.currentCalendarDayIndex是状态更新前的旧值,函数组件通过useRef来模拟这个旧值存储。
  • 将currentCalendarDayIndex加入useEffect的依赖数组,确保每次状态变化时effect都会执行,对应类组件监听状态更新的逻辑。

内容的提问来源于stack exchange,提问作者Tom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 16:25:39