Home > database >  Trouble converting a class to function in React Native
Trouble converting a class to function in React Native

Time:10-07

I'm trying to rewrite this code from class to a function. I've never used classes but I got this test code for a calendar app while learning react native but I seem to get stuck somewhere when I'm trying to replace componentDidUpdate to useEffect.

This is the old code:

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}
                    />
                ))
            }
        </>
    )
}

}

And this is the new code everything works except for some functions which has to do with the useEffect, I don't understand what properties I should add to get the same functionality as before. Thanks

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}
            />
        ))}
    </>
  )
}

CodePudding user response:

What this does:

useEffect(() => {
    if(currentCalendarDayIndex !== currentCalendarDayIndex){
        setLastCalendarDayIndex(currentCalendarDayIndex)
    }
},[]);

It runs the code inside useEffect every time the array changes. Because it's an empty array it will just run once (once the component mounts, this is basically the old ComponentDidMount), to mimic the behaviour of ComponentDidUpdate you need to keep track of the props so it should be a matter of passing them into the array (so React can track when it changes):

useEffect(() => {
    if(currentCalendarDayIndex !== currentCalendarDayIndex){
        setLastCalendarDayIndex(currentCalendarDayIndex)
    }
},[props]);

It's probably easier to change the destructuring you have in the component definition {row_days_array, month_index, current_month_index, chooseDifferentMonth} to props and then destructure a bit bellow, so you can use the whole object in you useEffect array

CodePudding user response:

You can pass a callback in setState to access previous state, and pass currentCalendarDayIndex in useEffect dependency to update lastedCalendarState every currentCalendar changes. Hope this can help!

useEffect(() => {
   setLastCalendarDayIndex((prevCalendarDayIndex) => 
       prevCalendarDayIndex !== currentCalendarDayIndex 
       ? currentCalendarDayIndex 
       : prevCalendarDayIndex)
}, [currentCalendarDayIndex])
  • Related