Occasionally I may want to unmount and remount a component with new data inside it. This could look like:
setAllPosts(undefined);
setAllPosts(newArrayOfPosts);
Because React batches state changes, depending on where the newArrayOfPosts is coming from, the state won't change. I've been able to hack a solution with a setTimeout() of 1 second and then filling in setAllPosts(), but this feels so wrong.
Is there a best practice way to tell React to slow down for a moment? or maybe to not batch update this particular state change?
P.S. I know there are better ways to do this, but I am working inside a third party environment and am pretty limited to what I have access to.
CodePudding user response:
Once react 18 is available (it's currently a release-candidate) there will be a function that can force updates to not be batched: flushSync
import { flushSync } from 'react-dom';
flushSync(() => {
setAllPosts(undefined);
});
flushSync(() => {
setAllPosts(newArrayOfPosts);
});
Until then, you may need to do the setTimeout approach (though it doesn't need to be a whole second).
P.S. I know there are better ways to do this, but I am working inside a third party environment and am pretty limited to what I have access to.
Yeah, if you can do something else that would probably be better. Most of the time, if you want to deliberately unmount/remount a component, that is best achieved by using a key
which you change when you want the remount to happen.
const [key, setKey] = useState(0);
const [allPosts, setAllPosts] = useState([]);
// ...
setKey(prev => prev 1);
setAllPosts(newArrayOfPosts);
// ...
return (
<SomeComponent key={key} posts={allPosts} />
)
CodePudding user response:
Occasionally I may want to unmount and remount a component with new data inside it.
It sounds like this use-case calls for a useEffect()
with a dependency based on something you care about, like another piece of state or prop being provided to this component.
useEffect(() => {
setAllPosts(newArrayOfPosts);
}, [shouldUpdate]);
I've even seen examples of people triggered useEffect()
with a dependency of a piece of state called count
or renderCount
. Not sure if this is necessarily best practice but it's one way to go about things.
const [count, setCount] = useState(0);
const [allPosts, setAllPosts] = useState([]);
useEffect(() => {
setAllPosts(props.values);
}, [count]);
const handleChange = () => {
setCount(prevCount => prevCount 1); // This will trigger your useEffect when handleChange() in invoked
}