Как использовать оператор распространения для обновления массива внутри объекта? - PullRequest
0 голосов
/ 22 апреля 2020

Что возвращает выборка, это список элементов. Я хочу добавить их в состояние.

const [state, setState] = useState({
  list: {
    items: [],
  }
});

fetch('http://example.com/list/')
  // GET response: [{ name: 'foo' }, { name: 'bar' }, { name: 'baz' }]
  .then((resList) => resList.json())
  .then((list) => {
    list.forEach(({ name }) => {
      const itemUrl = `https://example.com/list/${name}`;
      fetch(itemUrl)
        // GET responses: 
        // { name: 'foo', desc: '123' }
        // { name: 'bar', desc: '456' }
        // { name: 'baz', desc: '789' }
        .then((itemRes) => itemRes.json())
        .then((item) => {
          setState((prevState) => ({
            ...prevState,
            list: {
              items: [...state.list.items, item]
             },
           });
         })
       })
    }
  })

console.log(state);

// result: [{ name: 'baz', desc: '789' }]
// but wanted: [{ name: 'foo', desc: '123' }, { name: 'bar', desc: '456' }, { name: 'baz', desc: '789' }]

Ответы [ 2 ]

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

В вашем случае нет необходимости использовать prevState в setState.

Я подготовил для вас пример. Просто будьте осторожны при использовании крючков.

https://codesandbox.io/s/recursing-wood-4npu1?file= / src / App. js: 0-567

import React, { useState } from "react"
import "./styles.css"

export default function App() {
  const [state, setState] = useState({
    list: {
      items: [
        { name: "foo", desc: "123" },
        { name: "bar", desc: "456" },
      ],
    },
  })

  const handleClick = () => {
    setState(() => ({
      list: {
        items: [...state.list.items, { name: "baz", desc: "789" }],
      },
    }))
  }

  return (
    <div className="App">
      <button onClick={handleClick}>Click Me </button>
      <hr />
      {JSON.stringify(state)}
    </div>
  )
}
0 голосов
/ 22 апреля 2020

Вы не можете получить прямой доступ к обратному вызову для перехватчиков useState. Вот как вы можете обновить state после извлечения данных:

setState({
  ...state,
  list: {
    items:[...state.list.items, item]
  },   
});
...