将新子添加到嵌套状态对象

Add new child to nested state object

我想在 React 中创建一个树对象。我的初始状态有一个 name 变量和一个子对象数组。每次我遍历我的数据集时,我都想为我的子状态数组添加一个对象。

我的代码:

const [data, setData] = useState({ name: "Tree", children: [{}] });
  const regions = [
    {
      idregion: "region1",
      region_name: "South-Central Asia"
    },
    {
      idregion: "region2",
      region_name: "Balkan Peninsula"
    },
    {
      idregions: "region3",
      region_name: "Northern Africa"
    }
  ];
  
useEffect(() => {
    for (let reg of regions){
      setData((prevState) => {
        return {
          ...prevState,
          children: reg.region_name
        };
      });
    }
  }, []);

我试过了:

setData((prevState) => {
        return {
          ...prevState,
          children: [{ ...prevState }, { name: reg.region_name }]
        };
      });

setData((prevState) => {
        return {
          ...prevState,
          children: [{ ...prevState, name: reg.region_name }]
        };
      });

setData((prevState) => {
        return {
          ...prevState,
          children: [{ ...prevState.children, name: reg.region_name }]
        };
      });

我的目标是:

{
  name: 'Tree',
  children: [
    { name: 'South-Central Asia' },
    { name: 'Balkan Peninsula' },
    { name: 'Northern Africa' },
  ],
}

您的数组展开运算符展开了错误的对象:

return {
    ...prevState,
    children: [
        ...prevState.children,     // Copy the previous children over
        { name: reg.region_name }, // Add a new object with name field
    ]
};

我认为这就是你想要实现的:

function App() {
  const [data, setData] = React.useState({ name: 'Tree', children: [] });
  const regions = [
    {
      idregion: 'region1',
      region_name: 'South-Central Asia',
    },
    {
      idregion: 'region2',
      region_name: 'Balkan Peninsula',
    },
    {
      idregions: 'region3',
      region_name: 'Northern Africa',
    },
  ];

  React.useEffect(() => {
    setData((prevState) => ({
      ...prevState,
      children: regions.map((r) => ({ name: r.region_name })),
    }));
  }, []);

  return <pre>{JSON.stringify(data, null, 2)}</pre>;
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

你真的不应该在循环中使用 setState()。正如您在上面的示例中看到的,我遍历 regions 数组,使用 .map() 创建一个新数组并将 returned 值分配给 children 属性.一次。

您可以使用.map()创建一个新数组;对于数组中的每个项目,return 一个新对象,其中 nameregion_name

你可以这样做:

import React from "react";

const regions = [
  {
    idregion: "region1",
    region_name: "South-Central Asia",
  },
  {
    idregion: "region2",
    region_name: "Balkan Peninsula",
  },
  {
    idregions: "region3",
    region_name: "Northern Africa",
  },
];

const App = () => {
  const [data, setData] = React.useState({ name: "Tree", children: [{}] });

  const addRegions = () => {
    setData({ ...data, children: regions });
  };

  console.log(`data`, data);

  // can do it here
  // useEffect(() => {
  //   addRegions();
  // }, [])

  return (
    <div>
      <button onClick={addRegions}>Add regions</button>
    </div>
  );
};

export default App;

你可以这样做:

const [data, setData] = useState({ name: "Tree", children: [] });
  
  useEffect(() => {
    for (let reg of regions){
      setData((prevState) => {
        return {
          ...prevState,
          children: [...prevState.children, {name: reg.region_name}]
        };
      });
    }
  }, []);

但不是在 for 循环内设置状态,您可以像这样通过更新状态来做一些优化:

useEffect(() => {
    const children = regions.map(item => ({ name: item.region_name }));
    setData((prevState) => ({ ...prevState, children }))
  }, []);