Lo stato dell'array React non si aggiorna

Sep 17 2020

Voglio popolare sia lo stato dell'array ma projectItems non si aggiorna in useState e quando metto projectItems il componente esegue nuovamente il rendering. quindi, sto usando usecallback ma quando metto filteredItems e projectItems come array di dipendenze in useCallback e callback in useState, useCallback non viene mai eseguito.

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

Risposte

1 DrewReese Sep 17 2020 at 13:59

Problema

Gli aggiornamenti di stato vengono elaborati tra i cicli di rendering, quindi provare a registrarli o utilizzarli produrrà solo il valore del ciclo di rendering corrente , non quello che sarà nel ciclo di rendering successivo .

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

Soluzione

Usa un effetto hook per "reagire" projectItemsall'aggiornamento dello stato per attivare un filteredItemsaggiornamento.

...
setProjectItems(prevState => [...prevState, ...projectData]);

...

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

Appunti:

  • A meno che non callbackvenga effettivamente passato a un componente figlio, non penso sia necessario memorizzarlo.
  • Non penso projectItemsdovrebbe essere una dipendenza poiché la funzione di callback hook lo aggiorna.
  • filteredItems non è una dipendenza perché non è referenziato nella callback hook.
Nazeer Sep 17 2020 at 14:07

È possibile utilizzare un useEffectmetodo per aggiornare le modifiche all'array.

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