Search code examples
javascriptreactjsuse-effectuse-state

React useEffect doesn't block the re-render


I need to create a functional react component that automatically update the inner data every time there is a particular event.

I written the code below, but every time the callback is called the component is re-rendered and the variable myArray is set to empty array instead to be filled with all content coming in the callback.

What am I doing wrong? What's the approach I should use?

// event emulation
function onEventEmulator(callback, interval = 1000) {
    setInterval(() => callback('content'), interval);
}

function PollingComponent(props) {
    const [myArray, setMyArray] = useState([]);
    useEffect(() => {
        onEventEmulator(content => {
            setMyArray([...myArray, content]);
        });
    }, []); // with or without passing the empty array as second param, result does not change.
    return <ul>
        <li>Callback</li>
        <li>{myArray.length}</li>
    </ul>;
}

Solution

  • Let's try this:

    function onEventEmulator(callback, interval = 1000) {
      setInterval(() => callback("content"), interval);
    }
    

    And then:

    function PollingComponent(props) {
      const [myArray, setMyArray] = useState([]);
    
      useEffect(() => {
        onEventEmulator(content => {
          setMyArray(arr => [...arr, ...content]);
        });
      }, []);
    
      return (
        <ul>
          <li>Callback</li>
          <li>{myArray.length}</li>
        </ul>
      );
    }
    

    One thing that is missing here is a way to clear setInterval, but I guess that is not your concern here.