Search code examples
reactjsreact-redux

Can I use values from a redux store in an event listener without rerendering the element whenever the value is changed?


Consider the following component:

const ExampleComponent = () => {
    const dispatch = useDispatch();
    const bananaId = useSelector((store) => store.someSlice.bananaId);

    const onButtonClick = () => {
        dispatch(deleteFruit({ id: bananaId }));
    }
    
    return <button onClick={onButtonClick}>ClickMe</button>
}

Unless I'm mistaken, whenever bananaId changes, the ExampleComponent will rerender. This may cause performance issues, for instance, if I have many instances of ExampleComponent or if ExampleComponent is significantly more complex than just a button. And given that the id in this case isn't actually used for constructing the component HTML in any way, it seems to me like a rerender shouldn't be necessary.

Is there any way to avoid rerendering ExampleComponent whenever bananaId is changed? In my mind, the way to do this would be to avoid selecting it directly in the component function and instead somehow access it solely in the onButtonClick function. Is there a way to do that? Or some other way of avoiding the rerender?


Solution

  • Generally speaking, the component rerender due to the current code should not be very expensive, but if you are wanting to micro-optimize you can access the store within the callback using the useStore hook to access the Redux store instance, and then selecting the current bananaId value.

    Example:

    import { useStore } from 'react-redux';
    
    const ExampleComponent = () => {
      const store = useStore();
    
      const onButtonClick = React.useCallback(() => {
        const state = store.getState();
        const id = state.someSlice.bananaId;
    
        store.dispatch(deleteFruit({ id }));
      }, [store]);
        
      return <button onClick={onButtonClick}>ClickMe</button>
    }