Avoid re render with react hooks

10,376

Solution 1

React.memo can do the job, you can pass a custom equality check function to perform a rerender only when it returns a falsy value. I never faced a case where you want to completely ignore a value update from your Redux store, maybe it shouldn't be stored there ?

Memo API

eg: React.memo(Component, [areEqual(prevProps, nextProps)])

UseSelector API

Another way would be to use useSelector with a custom equality check function:

useSelector Redux API Reference

Connect API

If you still want to stick with mapStateToProps, you can also pass a custom equality check function as a parameter of the connect function:

areStatePropsEqual Redux API Reference

Edit: useRef solution

By using useRef, you store a mutable variable that will be kept as it is for the whole lifetime of the component.

Example based on yours:

const StoreMyVar = (WrappedComponent) => ({myVar, ...props}) => {
  const myRefVar = useRef(myVar)
  return <WrappedComponent myVar={myRefVar} {...props} />
}

const MyComponentWithImmutableVar = StoreMyVar(MyComponent)

Solution 2

The fastest way is React.memo, but you can use it just with functional components. Be careful, it is not tested.

const MyComponent(props) {
  return ...;
}

const areEqual(prevProps, nextProps) {
  return prevProps.myVar === nextProps.myvar
}

const mapStateToProps = state => ({
   myVar: state.myVar
});

export default React.memo(MyComponent, areEqual);
Share:
10,376

Related videos on Youtube

aabcabca12
Author by

aabcabca12

Updated on June 04, 2022

Comments

  • aabcabca12
    aabcabca12 almost 2 years

    I have some value that comes from Redux through props and I want to NOT render the component again when this value changes.

    I found some answers saying that I can use Memo but I don't know if this is the best option for my case?

    My "code":

    const MyComponent = () => {
        return ...;
    }
    
    const mapStateToProps = state => ({
      myVar: state.myVar
    });
    
    export default connect(mapStateToProps)(MyComponent);
    

    myVar changing shouldn't re render the component in this case.

    • Vencovsky
      Vencovsky over 4 years
      Please share your code. We can't give you any answer if we don't know what you are doing
    • aabcabca12
      aabcabca12 over 4 years
      @Vencovsky added code
  • aabcabca12
    aabcabca12 over 4 years
    it's a swiper component, the store saves the swiped ones, but if I re render using the swiped ones as reference it glitches out, however, other state change in the component doesn't break it, I'll try memo and see if it works, thanks!
  • aabcabca12
    aabcabca12 over 4 years
    I can't seem to get it to work, cause with that you compare previous props to next props, but I don't want to compare them, I just want to ignore the change of a single prop but acknowledge the other ones
  • Eld0w
    Eld0w over 4 years
    I think in your case I would delete the prop I want to ignore in both the prevProps and nextProps objects before returning a shallow comparison of the two resulting objects. (resuming to the default behaviour)
  • Eld0w
    Eld0w over 4 years
    I added another solution using the useRef hook in my post !