Правильный способ добавить элементы в массив, хранящийся в состоянии React с помощью ловушки useState? - PullRequest
0 голосов
/ 17 апреля 2020

Мне нужно объединить элементы в массив, хранящийся в состоянии компонента React. У меня есть пример на stackblitz, и я не могу понять, почему массив не растет, когда я добавляю элементы, используя оператор распространения, чтобы объединить существующий массив. Любая помощь приветствуется

ссылка: https://stackblitz.com/edit/react-usestate-example-ebzt6g?file=index.js

import React from 'react';
import { useState, useEffect } from 'react';
import { render } from 'react-dom';
import './style.css';

const App = () => {

    const [name, setName] = useState('React');
    const [coords, setCoords] = useState([]);

    const success = (position) => {
        // setCoords(coords.concat(position.coords))
        setCoords([
            ...coords,
            position.coords
        ])
        console.log("success! position=", position);
    }

    useEffect(() => {
        console.log("useEffect -> coords =", coords);
    });

    useEffect(() => {
        setInterval(() => {
            success({coords : {latitude: Math.random()*51, longitude: Math.random()*2.6}});
        }, 5000);
    }, []);

    return (
    <p>example to demonstrate growing an array stored with React usestate hook</p>
    )
}

render(<App />, document.getElementById('root'));


Ответы [ 3 ]

5 голосов
/ 17 апреля 2020
useEffect(() => {
  setInterval(() => {
    success({coords : {latitude: Math.random()*51, longitude: Math.random()*2.6}});
  }, 5000);
}, []);

Пустой массив, как говорит второй параметр, реагирует на создание этого эффекта только один раз и никогда не обновляет его. Когда он создан, он имеет ссылку на функцию успеха в своем закрытии, а эта функция успеха в свою очередь имеет ссылку на coords. Поскольку это все с первого рендера, coords - пустой массив.

Так что каждый раз, когда вы вызываете success, вы добавляете новые координаты в этот пустой массив и вызываете setCoords. Массив никогда не увеличивается, потому что вашей отправной точкой всегда является пустой массив. И вы никогда не увидите новые массивы, потому что они существуют только при более поздних рендерах.

Самое простое решение для этого - использовать функциональную версию setCoords. React вызовет функцию и передаст последнее значение координаты

const success = (position) => {
  setCoords(prevCoords => {
    return [
      ...prevCoords,
      position.coords
    ]
  })
}
0 голосов
/ 18 апреля 2020

Спасибо Nicholas Tower за правильный ответ.

const success = (position) => {
  setCoords(prevCoords => {
    return [
      ...prevCoords,
      position.coords
    ]
  })
}

исправляет проблему.

0 голосов
/ 17 апреля 2020

Ну, у меня была эта проблема, и благодаря кому-то, кто помог мне разобраться, как решить эту проблему, сначала вы должны клонировать координаты, а затем вы добавляете новые координаты к клону, а затем вы устанавливаете новые координаты клона. в состояние, подобное этому:

 const success = (position) => {
  let clonedCoords = [...coords];
  setCoords([...clonesCoords, position.coords]);
  console.log("success! position=", position);
};

это должно работать, если нет, вы не можете ответить, поэтому я могу помочь вам больше

...