user2159616
user2159616

Reputation: 57

Using setInterval and updating state inside useEffect how to prevent other component to re-render

I have 2 components List.js and Counter.js. Under App.js after the DOM render I need the setInterval to trigger each second showing the incremental count. Also there is a list that should only trigger when manually submitted.

App.js

export default function App() {
  const addtolist = useRef();
  const [item, setItem] = useState([]);
  const [count, setCount] = useState(0);

  useEffect(() => {
     let timer = setInterval(() => {
       setCount((count) => count + 1);
     }, 1000);
     return () => {
       clearInterval(timer);
     };
  }, []);

  const submitHandler = () => {
    setItem((item) => [...item, addtolist.current.value]);
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <input type="text" name="addtolist" ref={addtolist} />
      <button onClick={submitHandler}>Submit</button>
      <Counter count={count} />
      <List data={item} />
    </div>
  );
}

The problem above is each time the count is set the List component also renders. Need to prevent that from re-rendering. The List component should only render when item state is set.

Upvotes: 0

Views: 36

Answers (1)

Arkellys
Arkellys

Reputation: 7780

Updating the state of a component will trigger a re-render for this component. And by default, when a component re-render its children will also re-render.

To prevent <List> from re-rendering when count changes, simply move your useEffect and count state in <Counter> or on a separate component wrapping <Counter>:

const CounterContainer = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
     let timer = setInterval(() => {
       setCount((count) => count + 1);
     }, 1000);
     return () => {
       clearInterval(timer);
     };
  }, []);

  return <Counter count={count} />
}

Upvotes: 1

Related Questions