I have a component:
const MyComp : React.FC<{ editing?: Data }> = ({editing = { title = '', description = '', date: new Date() } }) => {
const [data, setData] = useState<Data>({...editing})
useEffect(() => setData({...editing}), [editing])
return (/* use data inside here to render component */)
}
The problem is that the useEffect is looping, so React is detecting that the editing prop is changing every, the thing is that i use MyComp without any props like this:
<MyComp></MyComp>
This is really confusing me, i'm kinda lost now on how React works, any ideas on why is this happening?
Because editing is an object. Objects are compared by reference. If you don't pass the prop editing to the component, in each render, editing will receive a new link in memory, because you passing a default value to it. So useEffect will assume that dependencies have changed.
You can set primitive types to dependencies.
const MyComp : React.FC<{ editing?: Data }> = ({editing = { title = '', description = '', date: new Date() } }) => {
const [data, setData] = useState<Data>({...editing})
useEffect(() => setData({...editing}), [editing.title, editing.description, editing.date.getTime()])
return (/* use data inside here to render component */)
}
It happens because useEffect uses shallow comparison. You can either destructure the object
const {param1, param2} = editing;
useEffect(() => {
//logic goes here
}, [param1, param2]);
Or write a custom hook that uses Lodash isEqual for example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With