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
相关产品推荐
相关产品推荐

