Tom
Tom

Reputation: 115

Trouble converting a class to function in React Native

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

Upvotes: 0

Views: 48

Answers (2)

Phr0gggg
Phr0gggg

Reputation: 138

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])

Upvotes: 1

Pedro Filipe
Pedro Filipe

Reputation: 1075

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

Upvotes: 2

Related Questions