7

I just want to get a value once from the redux store, and use it once inside of a useEffect function.

However useSelector is required to be on the root level of a component, so it is run every render. This means if the value in my redux store is updated, all the child components get updated too.

I don't want that to happen. (For some reason, the redux update is interrupting some of my animations). I only want it to access useSelector once when the component is mounted.

How can I accomplish this?

Current, unwanted behavior:

const Test = () => {
    const select = useSelector(state=> state); // updates every dispatch
    
    useEffect(()=> {
       console.log(select.value);
       }, []);
...
}

Wanted behavior, if react would let me...

const Test = () => {
    useEffect(()=> {
       const select = useSelector(state=> state); // only accessed once, doesn't update children on later dispatches
       console.log(select.value);
       }, []);
...
}
Qrow Saki
  • 932
  • 8
  • 19

2 Answers2

11

You can use the equality check function of useSelector:

const select = useSelector(state => state, () => true);

By returning always true, you prevent updates to the data selected on mount in that component and thus the re-renders.

Omar
  • 16,329
  • 10
  • 48
  • 66
  • 1
    Boy I can always depend on SO in a pinch before I start writing ugly code xD. Thank you for this insight! – takanuva15 Jul 15 '23 at 00:16
5

You could just grab the store and get the state using that. The store will not change, as long as you're not changing the store passed to the React Redux <Provider>.

const Test = () => {
  const store = useStore();
  console.log('Test rendered')

  useEffect(() => {
    const value = store.getState().value;
    console.log('useEffect value: ', value)
  }, [store]);

  // ...
};
cbr
  • 12,563
  • 3
  • 38
  • 63