Object as an atom will cause re-render even when use selector?
See original GitHub issueimport * as React from "react";
import { atom, useRecoilValue, useSetRecoilState, selector } from "recoil";
import "./App.css";
const valueState = atom({
key: "value",
default: { a: 1, b: 2 },
});
const selectA = selector({
key: "selectA",
get: ({ get }) => get(valueState).a,
});
function ValueChild() {
const { a } = useRecoilValue(valueState);
return <div>useRecoilValue a:{a}</div>;
}
function SelectorChild() {
const a = useRecoilValue(selectA);
return <div>useRecoilValue + Selector a:{a}</div>;
}
function App() {
const setValues = useSetRecoilState(valueState);
const onlyChangeB = () => {
setValues((v) => ({ ...v, b: 3 }));
};
return (
<div className="App">
<ValueChild />
<SelectorChild />
<button onClick={onlyChangeB}>update</button>
</div>
);
}
export default App;
Bootstrapped a new create-react-app and play with it.
I declared an atom as an object { a: 1, b: 2 }
with 2 components which consume it:
<ValueChild>
only subscribe to propertya
<SelectorChild>
only subscribe to propertya
with selector
Expect:
change property b
should not trigger re-render of components who subscribe to property a
Actual behavior
when I click the button to update only b
’s value, both components will get re-rendered.
Anything I am missing here? Thanks. Very nice API and idea. I love the work. Tried to replace redux/mobx with this. But this will be a blocker
Issue Analytics
- State:
- Created 3 years ago
- Comments:12 (4 by maintainers)
Top Results From Across the Web
useSelector causing rerender despite using shallowEqual?
useSelector will cause a second re-render despite I've added shallowEqual . Have I understood the concept of using this shallowEqual wrongly?
Read more >Bonus: Performance - Recoil
This component is subscribed to filteredTodoListState , so it will re-render whenever that state changes or when its parent component, TodoList , re-renders....
Read more >Lessons learned from moving to Recoil.js - Kitemaker blog
Fortunately, it's pretty simple - if a selector returns a simple value (string, number, boolean), it triggers a re-render whenever that value ...
Read more >Re-Render Large Lists Optimally When States Change in ...
In this article, we are going to look at how we can use Recoil's atom, selector, and hooks to display and update a...
Read more >Hooks | React Redux
However, when an action is dispatched to the Redux store, useSelector() only forces a re-render if the selector result appears to be different...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Hi @rwieruch, the reason all three update is because each
itemSelector
reads and updateslistState
. If a selector’s dependencies change then the component will be re-rendered, even if the resulting selector value does not change. To isolate component updates from each other, then the atoms and selectors all need to be isolated from each other.Something like this should work:
Subscriptions are based on individual atoms and selectors. Currently, all downstream subscribers of an atom or selector will update when a dependency updates. If you wish to have your component only update when a or b is updated, then they can be modeled as separate atoms.
Internally, we’re working on a mechanism to limit updates when the values have not changed. But, we’re planning to really clean up that API before publishing it.