Is there a way to shorthand useSelector instead of causing unnecessary renders?

Viewed 82

Consider both these calls

const loading = useSelector((state) => state.example.loading); 
const { loading } = useSelector((state) => state.example);

const { loading } = useSelector((state) => state.example); would make the component cause an unnecessary render whenever the other variable in the example slice changes. This one const loading = useSelector((state) => state.example.loading); wont because it only gets the loading variable.

In an app that I'm cleaning up a group member wrote const { var1, var2, var3....var50 } = useSelector((state) => state.example); and its causing unnecessary renders throughout the app. Instead of rewriting

const var1 = useSelector((state) => state.example.var1);
const var2 = useSelector((state) => state.example.var2);
...

Is there anyway to shorthand this but without causing a render?

playground example:

https://codesandbox.io/s/cool-dew-7pfclw?file=/src/Header.js

2 Answers

Yes and no. You could create an object with all the values you actually want and then use a shallow compare with your reducer to make sure it doesn't rerender too often.

It might be less code, but honestly I'm not sure if it would be more readable.

You could also look into other selector libraries using proxies to track when to update. there are some alternative candiates mentioned in the redux docs, you might be interested in proxy-memoize.

Define the variable you want to get: let var1, var2, var3, var4, ...;

Assign value to those variable inside useSelector function:

let var1, var2, var3, var4, var5...;
const obj = useSelector(({example}) => {var1 = example.var1; var2 = example.var2; var3 = example.var3; var4 = example.var4; var5 = example.var5
  return {var1, var2, var3, var4, var5}
 });

Example of your playground example: https://codesandbox.io/s/inspiring-bhabha-9b9qoq?file=/src/Header.js

Related