Reputation: 4450
In the code below, whenever I get new props from the parent, the new props are logged correctly on the console, but the rendered HTML is never updated after the initial render:
export default function(props) {
const [state, setState] = useState(props)
// initially, props.something is defined
// every time props changes (from the parent) props.something is redefined as expected and logged here
console.log(props.something)
// initially, props.something is rendered correctly
// every time props.something changes (from the parent) the HTML never updates
return (
{state.something && <div>{state.something}</div>}
)
}
I already tried using useEffect()
even though I don't see the point, but it it didn't fix anything.
Upvotes: 5
Views: 9382
Reputation: 102257
You might not need an effect to sync state from props, See Resetting all state when a prop changes. You can pass a key
prop to the component so that whenever the key
changes, React will recreate the DOM and reset the state of the component and all of its children
import { useState } from 'react';
const MyComponent = (props) => {
const [state, setState] = useState(props);
console.log(props.something);
return state.something ? <div>{state.something}</div> : null;
};
function App() {
const [count, setCount] = useState(0);
return (
<>
<button onClick={() => setCount((count) => count + 1)}>increase</button>
<MyComponent something={count} key={count} />
</>
);
}
export default App;
Upvotes: 1
Reputation: 14609
State will not update just because props change, this is why you need useEffect
.
export default function(props) {
const [state, setState] = useState(props)
useEffect(() => {
setState(props.something)
}, [props.something])
// initially, props.something is defined
// every time props changes (from the parent) props.something is redefined as expected and logged here
console.log(props.something)
// initially, props.something is rendered correctly
// every time props.something changes (from the parent) the HTML never updates
return (<div>{state.something}</div>)
}
adding props.something
to the array as the second argument to useEffect
tells it to watch for changes to props.something
and run the effect when a change was detected.
Update: In this specific example, there is no reason to copy props to state, just use the prop directly.
Upvotes: 9
Reputation: 703
In your example you copy props to state only once, when initial values set.
It's almost never a good idea to copy props to component state though. You can read about it react docs
Upvotes: 1