React array state is not updating

88 views Asked by At

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]);
2

There are 2 answers

6
Drew Reese On BEST ANSWER

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:

  • Unless callback is actually getting passed to a child component I don't think it's necessary to memoize it.
  • I don't think projectItems should be a dependency since the hook callback function updates it.
  • filteredItems isn't a dependency because it isn't referenced in the hook callback.
0
Nazeer On

You can use a useEffect method to update the changes to array.

useEffect(() => {
  setfilteredItems([...projectItems]);
}, [projectItems]);