简体   繁体   English

如何使用 setState 向数组 Object state 添加更多对象?

[英]How to add more objects to Array Object state using setState?

This is my initial data这是我的初始数据

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

I want to loop over and:我想循环并:

  • Where it has name 1 add that object to stateOnename 1的地方,将 object 添加到stateOne
  • Where it has name 2 add that object to stateTwoname 2的地方,将 object 添加到stateTwo

End goal both states needs to have Array of Objects inside:最终目标两个州都需要在里面有对象数组:

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

This is what i've tried:这是我尝试过的:

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)
}

I'd prefer sending data as a prop to that component我更喜欢将data作为道具发送到该组件

You can achieve what you need by您可以通过以下方式实现您所需要的


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)
  }, [])
}

setState functions as an assignment. setState 用作赋值。 Like you would normally assign a variable.就像您通常会分配一个变量一样。 That means if you want to add something to an array, you need to include that array in the assignment.这意味着如果您想向数组中添加某些内容,则需要将该数组包含在赋值中。

Something like this:像这样的东西:

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

If you don't want to use filter twice for whatever reason, You can create temporary array for each one and manipulate them then update each state respectively like so:如果您不想出于任何原因使用两次过滤器,您可以为每个临时数组创建并操作它们,然后分别更新每个 state,如下所示:

  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); 

The problem with what you're doing is you're updating the state each time you find a match which will cause a lot of unnecessary re-renders.您所做的问题是每次找到匹配项时都会更新 state ,这将导致大量不必要的重新渲染。

You've said that data comes from some API you're querying.您说过data来自您正在查询的一些 API。 If so, filter the data once you get it.如果是这样,请在获得数据后对其进行过滤。 You can do that in a couple of ways.你可以通过几种方式做到这一点。

With two calls to filter :通过两次调用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...
};

Or if you don't want to make two passes through the data, a single loop:或者,如果您不想通过数据进行两次传递,则使用单个循环:

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...
};

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
    )
   
  };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM