Search code examples
reactjsreact-hookslodash

How do I reference previous state in lodash's filter method?


const [panelRight, setPanelRight] = useState(sample(filter(menu, (el) => el !== panelLeft)));

useEffect(() => {
    const interval = setInterval(() => {

    const menuCategory = filter(menu, (el) => el !== panelLeft && el !== panelRight);

    setPanelRight(sample(menuCategory));

   }, 10000);

Currently panelRight is being set to the same random menu element every time the the setInterval is called. I think this might be because I need to reference the previous state in the filter method, but how?


Solution

  • Your code lacks details, we dont know what is in your useEffect deps so lets assume and guess. Provide more details next time, please.

    Lets assume your useEffect has an empty [] dependencies array and called only once on the first render.

    So the issue - setInterval will always hold the value it had initially when the setInterval callback (closure) was defined. Values from the first render.

    And here is what you should do:

    // Insert that before or after your setStates section
    const panelRightRef = React.useRef();
    const panelLeftRef = React.useRef();
    
    // That will update ref variables
    useEffect(() => {panelRightRef.current = panelRight}, [panelRight]);
    useEffect(() => {panelLeftRef.current = panelLeft}, [panelLeft]);
    
    useEffect(() => {
        const interval = setInterval(() => {
            // if menu is also a State variable and is not immutable - you should add useRef() for it
            const menuCategory = filter(menu, (el) => el !== panelLeftRef.current && el !== panelRightRef.current);
            setPanelRight(sample(menuCategory));
        }, 10000);
    
        // that will be called on depsarray changes or when component is destroyed
        return () => clearInterval(interval);
    }, []);