react-ridge-state icon indicating copy to clipboard operation
react-ridge-state copied to clipboard

Components Re-rendering

Open JakeNap opened this issue 4 years ago • 4 comments

Given the following example my understanding is that Component should only re-render when value changes. But it seems that because useSelector internally uses use which uses useState you are essentially subscribing to the entire state update but just returning a filtered value? So Component re-renders whenever anything in state changes? Or have I misunderstood something?

// state.js
export const exampleState = newRidgeState({ count: 0, value: 0 });
setInterval(() => {
  // we are only updating the count value
  exampleState.set(x => ({...x, count: x.count + 1 }));
}, 100);
// component.js
const Component = ({ children }) => {
  console.log("Render: ExampleInner");
  // we want to subscribe to only changes to value and only rerender if value changes
  const exampleValue = exampleState.useSelector(x => x.value);
  return ( ... );
};

JakeNap avatar Aug 05 '21 15:08 JakeNap

The desired behaviour is not re-rendering on state updates when deep value of selector has not changed. It should work!

RichardLindhout avatar Aug 05 '21 22:08 RichardLindhout

Hmm yeah this is what I thought but I can't see how this can be achieved. Because in the code the use function is doing:

const [state, setState] = useState();
sub(setState);

So anytime the subscriber fires it is going to cause a re-render.

Here is a code sandbox showing this:

https://codesandbox.io/s/peaceful-http-lk8bx?file=/src/App.js

Shouldn't useSelector subscribe to the state updates directly so it can filter on the value and then setState accordingly? Instead of using the use function?

JakeNap avatar Aug 06 '21 08:08 JakeNap

I've opened a PR that I believe fixes this issue. (Sorry for the confusing account switching 😂 Me and JakeNap are the same person).

https://github.com/web-ridge/react-ridge-state/pull/19

Let me know what you think? I've tested this tweak in the PR and it fixes my issue and I think it's how useSelector should handle state updates. But there maybe some context I'm missing as to why this library doesn't do this already.

GeraldHost avatar Aug 06 '21 09:08 GeraldHost

@RichardLindhout any thoughts on this?

GeraldHost avatar Aug 19 '21 10:08 GeraldHost