reactjsreact-reduxreact-hooksreact-router-component

React array state is not updating


I want to populate both the array state but projectItems doesn't update in useState and when i put projectItems the component re-renders. so, i am using usecallback but when i put filteredItems and projectItems as dependency array in useCallback and callback in useState, useCallback never runs.

const [filteredItems, setfilteredItems] = useState([]);
const [projectItems, setProjectItems] = useState([]);

const { projects } = props;


const callback = useCallback(() => {
        console.log('callback');
        const projectData = projects.map(i => {
            return (
                {
                    key: '1',
                    projectName: i.project_name,
                    size: i.size,
                    location: i.location,
                    status: `Day ${i.Finished_events_days}/${i.total_days_needed}`,
                    score: `${i.score}/10`,
                    view: <a>View Project</a>,
                    download: <a>Download</a>,
                    feedback: <a>Feedback</a>,
                    audit: <a>Audit</a>
                })
        });

        setProjectItems(prevState => [...prevState, ...projectData]);
        console.log(projectItems);
        setfilteredItems([...projectItems]);
    }, [projectItems, filteredItems]);

    useEffect(() => {

    }, [callback]);

Solution

  • Issue

    State updates are processed between render cycles, so trying to log or use it will only yield the value from the current render cycle, not what it will be in the next render cycle.

    setProjectItems(prevState => [...prevState, ...projectData]);
    console.log(projectItems); // <-- current state!
    setfilteredItems([...projectItems]); // <-- current state!
    

    Solution

    Use an effect hook to "react" to the projectItems state update to trigger a filteredItems update.

    ...
    setProjectItems(prevState => [...prevState, ...projectData]);
    
    ...
    
    useEffect(() => {
      console.log(projectItems); // <-- updated state!
      setfilteredItems([...projectItems]); // <-- updated state!
    }, [projectItems]);
    

    Notes: