Durgesh
Durgesh

Reputation: 21

Just need a small solution for not rendering a component in react app

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

Answers (1)

jsejcksn
jsejcksn

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

Related Questions