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