如何使用 setState 将更多对象添加到数组对象状态?

时间:2021-02-17 11:40:10

标签: javascript reactjs setstate

这是我的初始数据

const data = [
  { id: '1', name: '1' },
  { id: '2', name: '1' },
  { id: '3', name: '2' },
]

我想循环和:

  • 在它有 name 1 的地方将该对象添加到 stateOne
  • 在它有 name 2 的地方将该对象添加到 stateTwo

最终目标两个状态都需要内部有对象数组:

  • stateOne 需要看起来像
[
  { id: '1', name: '1' },
  { id: '2', name: '1' }
]
  • stateTwo 需要看起来像
[
  { id: '3', name: '2' },
]

这是我试过的:

const data = [
  { id: '1', name: '1' },
  { id: '2', name: '1' },
  { id: '3', name: '2' },
]

const Testing = () => {
  const [stateOne, setStateOne] = useState([])
  const [stateTwo, setStateTwo] = useState([])

  useEffect(() => {
    data.forEach((e) => {
      if (e.name === '1') {
        console.log('e', e)
        setStateOne((prevSate) => ({ ...prevSate, e }))
      }
      // if (e.name === '2') {
      //   setStateTwo(e)
      // }
    })
  }, [])

  console.log('stateOne', stateOne)
}

5 个答案:

答案 0 :(得分:2)

我更愿意将 data 作为道具发送给该组件

您可以通过以下方式实现您的需求


const data = [
  { id: '1', name: '1' },
  { id: '2', name: '1' },
  { id: '3', name: '2' },
]

export default function Testing() {

  const [stateOne, setStateOne] = useState([])
  const [stateTwo, setStateTwo] = useState([])

  useEffect(() => {
    setStateOne(data.filter(e => e.name === "1"))
    setStateTwo(data.filter(e => e.name === "2"))    
    console.log('stateOne', stateOne)
    console.log('stateTwo', stateTwo)
  }, [])
}

答案 1 :(得分:1)

setState 用作赋值。就像您通常会分配一个变量一样。这意味着如果你想向一个数组添加一些东西,你需要在赋值中包含该数组。

像这样:

      if (e.name === '1') {
        console.log('e', e)
        setStateOne([...stateOne, e])
      }
      if (e.name === '2') {
         setStateTwo([...stateTwo, e])
      }

答案 2 :(得分:1)

如果您不想因任何原因使用过滤器两次,您可以为每个创建临时数组并操作它们,然后分别更新每个状态,如下所示:

  const [stateOne, setStateOne] = useState([]);
  const [stateTwo, setStateTwo] = useState([]);

  useEffect(() => {
    const tempArr1 = [];
    const tempArr2 = [];

    data.forEach((item) => {
      if (item.name === "1") {
        tempArr1.push(item);
      } else if (item.name === "2") {
        tempArr2.push(item);
      }
    });

    setStateOne(tempArr1);
    setStateTwo(tempArr2);
  }, []);

  console.log(stateOne);
  console.log(stateTwo); 

您所做的问题是每次找到匹配项时都会更新状态,这会导致大量不必要的重新渲染。

答案 3 :(得分:0)

您说过 data 来自您正在查询的某些 API。如果是这样,请在获得数据后对其进行过滤。您可以通过多种方式做到这一点。

两次调用 filter

const Testing = () => {
    const [stateOne, setStateOne] = useState([]);
    const [stateTwo, setStateTwo] = useState([]);

    useEffect(() => {
        let cancelled = false;
        getTheData(data => {
            if (cancelled) {
                return;
            }
            setStateOne(data.filter(({name}) => name === "1"));
            setStateTwo(data.filter(({name}) => name === "2"));
        };
        return () => {
            // So we don't try to set setate on an unmounted component
            cancelled = true;
        };
    }, []);

    // ...use `dataOne` and `dataTwo` here...
};

或者,如果您不想对数据进行两次传递,则进行一次循环:

const Testing = () => {
    const [stateOne, setStateOne] = useState([]);
    const [stateTwo, setStateTwo] = useState([]);

    useEffect(() => {
        let cancelled = false;
        getTheData(data => {
            if (cancelled) {
                return;
            }
            const stateOne = [];
            const stateTwo = [];
            for (const entry of data) {
                switch (entry.name) {
                    case "1":
                        stateOne.push(entry);
                        break;
                    case "2": // or default if you want all non-1s in `stateTwo`
                        stateTwo.push(entry);
                        break;
                }
            }
            setStateOne(stateOne);
            setStateTwo(stateTwo);
        };
        return () => {
            // So we don't try to set setate on an unmounted component
            cancelled = true;
        };
    }, []);

    // ...use `dataOne` and `dataTwo` here...
};

答案 4 :(得分:0)


const data = [
    { id: "1", name: "1" },
    { id: "2", name: "1" },
    { id: "3", name: "2" }
  ];
  
  const App = () => {
    const newdata = useState(data);
    const [stateOne, setStateOne] = useState([]);
    const [stateTwo, setStateTwo] = useState([]);
  
    const Filter = () => {
      let listOne = [];
      let listTwo = [];
      newdata[0].map((it) => {
        if (it.name === "1"){
          listOne.push(it);
        }
        else if(it.name === "2"){
          listTwo.push(it)
        }
      });
      setStateOne(listOne);
      setStateTwo(listTwo);
    };
  
    useEffect(() => {
      Filter();
    }, []);

    console.log("stateOne", stateOne)
    console.log("stateTwo", stateTwo)

    return (
      // your code
    )
   
  };