Установить состояние, стирающее предыдущее значение объекта Реагировать

#reactjs #setstate

#reactjs #setstate

Вопрос:

Я пытаюсь выполнить последующие вызовы API, чтобы получить информацию о некоторых финансовых индексах.. После каждого вызова я хочу обновить de indexObject, чтобы он содержал все данные из всех индексов, которые я сохранил в массиве индексов. Проблема в том, что каждый раз, когда вызывается setIndexObject, он перезаписывает объект, теряя предыдущее значение, даже когда я использую оператор распространения.

  const [indexObject, setIndexObject] = useState({});

  const indexes = [
    "^GDAXI",
    "^BVSP",
    "^NDX",
    "^DJI",
    "^GSPC",
    "^IBEX",
    "^HSI",
    "^BSESN",
    "^FTSE",
  ];

  useEffect(() => {
    indexes.forEach((index) => {
      const options = {
        method: "GET",
        url:
          "https://apidojo-yahoo-finance-v1.p.rapidapi.com/stock/v2/get-summary",
        params: { symbol: `${index}`, region: "US" },
        headers: {
          "x-rapidapi-key":
            "----",
          "x-rapidapi-host": "apidojo-yahoo-finance-v1.p.rapidapi.com",
        },
      };

      axios
        .request(options)
        .then(function (response) {
          setIndexObject({
            ...indexObject,
            [index]: {
              value: response.data.price.regularMarketPrice.fmt,
              variation: response.data.price.regularMarketChangePercent.fmt,
            },
          });
        })
        .catch(function (error) {
          console.error(error);
        });
    });
  }, []);
 

Это то, чего я пытаюсь достичь:

 {
    A:{
      value:,
      variation:,
    },
    B:{
      value:,
      variation,
    }
  }
 

Спасибо за помощь!

Комментарии:

1. Если вы добавляете и удаляете подобные объекты подобным образом, не будет ли массив объектов лучшим типом данных для вашего состояния?

2. При использовании текущего состояния для обновления состояния всегда используйте версию обратного setState вызова . Кроме того, является ли вызов axios в a useEffect ?

3. что такое индекс и как вы его обновляете? кажется, что индекс prop не меняется

4. могу ли я узнать, откуда это [ index ] ? и как вы называете этот запрос axios (нажатие кнопки или useffect или что)?

5. Исходное значение indexObject фиксируется закрытием. Используйте форму обратного вызова setState, упомянутую выше, чтобы получить текущее значение при попытке обновления.

Ответ №1:

Проблема здесь в том, что вы зацикливаете запрос, в то время setState как он не синхронен. Лучше сначала заполнить все данные, а затем установить состояние после этого.

 const [indexObject, setIndexObject] = useState({});

const handleFetchData = async () => {
  const indexes = [
    "^GDAXI",
    "^BVSP",
    "^NDX",
    "^DJI",
    "^GSPC",
    "^IBEX",
    "^HSI",
    "^BSESN",
    "^FTSE",
  ];
  const resultData = {};

  for(const index of index) {
    const response = await axios.request(); // add your own request here
    
    resultData[index] = response;
  }

  return resultData;
}

useEffect(() => {
  handleFetchData().then(data => setIndexObject(data));
}, []);
 

почему я использую for of ? потому forEach что или .map не может ожидать асинхронного цикла.
Или, если вы хотите получить все данные одновременно, вы можете рассмотреть возможность использования Promise.all

Комментарии:

1. Спасибо! Он работал с использованием функции обратного вызова setState, но этот способ работает лучше!