Reputation: 21
i have used memo to not rerender the RenderButtons
component but is there any way in react to fully stop rerender and like avoid the extra computational computation for memo and entirely avoid use of memo
or useMemo
or it is the very nature if recoil
library ?
import { memo } from 'react';
import { RecoilRoot, atom, useRecoilState, useRecoilValue } from 'recoil';
const countAtom = atom({
key: 'countState',
default: 0,
});
function App() {
return (
<RecoilRoot>
<div>
<RenderCount />
<RenderButtons />
</div>
</RecoilRoot>
);
}
function RenderCount() {
const count = useRecoilValue(countAtom);
return <h1>{count}</h1>;
}
const RenderButtons = memo(() => {
const [count, setCount] = useRecoilState(countAtom);
return (
<div>
<button onClick={() => setCount(count + 1)}>Add + 1</button>
<button onClick={() => setCount(count - 1)}>Subtract - 1</button>
</div>
);
});
export default App;
Upvotes: 1
Views: 42
Reputation: 33856
You can use the hook useSetRecoilState
to get the immutable setter function… which won't trigger a re-render of the component that uses it:
body { font-family: sans-serif; }
<div id="root"></div><script src="https://cdn.jsdelivr.net/npm/[email protected]/umd/react.development.js"></script><script src="https://cdn.jsdelivr.net/npm/[email protected]/umd/react-dom.development.js"></script><script src="https://cdn.jsdelivr.net/npm/@babel/[email protected]/babel.min.js"></script><script src="https://cdn.jsdelivr.net/npm/[email protected]/umd/index.min.js"></script>
<script type="text/babel" data-type="module" data-presets="env,react">
// This Stack Overflow snippet demo uses UMD modules
const { useRef } = React;
const { RecoilRoot, atom, useRecoilValue, useSetRecoilState } = Recoil;
function useRenderCount() {
const renderCountRef = useRef(0);
renderCountRef.current += 1;
return renderCountRef.current;
}
const countAtom = atom({
key: "countState",
default: 0,
});
function RenderCount() {
const count = useRecoilValue(countAtom);
const renderCount = useRenderCount();
return (
<div>
<h1>Count: {count}</h1>
<p>Count render count: {renderCount}</p>
</div>
);
}
function RenderButtons() {
const setCount = useSetRecoilState(countAtom);
const renderCount = useRenderCount();
return (
<div>
<button onClick={() => setCount((count) => count + 1)}>Add + 1</button>
<button onClick={() => setCount((count) => count - 1)}>
Subtract - 1
</button>
<p>Buttons render count: {renderCount}</p>
</div>
);
}
function App() {
return (
<RecoilRoot>
<div>
<RenderCount />
<RenderButtons />
</div>
</RecoilRoot>
);
}
ReactDOM.createRoot(document.getElementById("root")).render(<App />);
</script>
Upvotes: 0