【问题标题】:Update an array inside an object with unique value in react with hook在与钩子反应中更新具有唯一值的对象内的数组
【发布时间】:2021-12-08 04:48:24
【问题描述】:

我有一个两个选择列表,我可以从中选择值

列出一个=“A”、“B”

列出两个 = “C”、“D”、“E”、“F”

我有一个反应状态 const [filterTags, setFilterTags] = useState({ one: [], two: [] });

我可以从updateValue(val) 中的任何列表中一次传递一个 val 我需要以这样的方式更新filterTags,如果它的val来自列表one,即AB,它应该像这样更新状态 {one:["A"]: two:[]}

const updateValue = (val) => {
        if (val === 'A' || val === 'B') {
            setFilterTags({ one: val });
        } else {
            setFilterTags({ ...filterTags, two: val });
        }
    };

如果我一一传递A C C D B A E C,它应该用唯一值更新数组,输出应该是

{one:["A"]: two:[]} //passing A
{one:["A"]: two:["C"]} //passing C
{one:["A"]: two:["C"]} // same since C is already there in two on passing C
{one:["A"]: two:["C","D"]} //passing D
{one:["A","B"]: two:["C","D"]}  //passing B
{one:["A","B"]: two:["C","D"]} //same since A is already present in one on //passing A
{one:["A","B"]: two:["C","D","E"]} //passing E
{one:["A","B"]: two:["C","D","E"]}// final output on passing C

它应该使用唯一值更新相应的元素 现在上面的代码只能更新一个值

【问题讨论】:

    标签: javascript arrays reactjs object react-hooks


    【解决方案1】:

    在设置状态时,使用functional updates 选项来获取先前的值(prev),并使用传播来创建具有先前和更新值的新状态。使用 Set 来维护唯一值。

    const updateValue = (val) => {
      if (val === 'A' || val === 'B') {
        setFilterTags(prev => ({ ...prev, one: [...new Set([...prev.one, val])] }));
      } else {
        setFilterTags(prev => ({ ...prev, two: [...new Set([...prev.two, val])] }));
      }
    };
    

    这里代码怎么重复太多了,因为设置状态的逻辑都是一样的,只是key发生了变化,所以你可以重构一下:

    const updateValue = (val) => {
      const key = val === 'A' || val === 'B' ? 'one' : 'two';
      
      setFilterTags(prev => ({ ...prev, [key]: [...new Set([...prev[key], val])] }));
    };
    

    您也可以将Array.includes 用作suggested by Houssam 以避免更新状态:

    const updateValue = (val) => {
      const key = val === 'A' || val === 'B' ? 'one' : 'two';
    
      setFilterTags(prev => {
        const key = val === 'A' || val === 'B' ? 'one' : 'two';
        
        return prev[key].includes(val)
          ? prev
          : { ...prev, [key]: [...prev[key], val] };
      });
    };
    

    【讨论】:

    • 它将返回一个集合而不是我认为的数组
    • 使用 spread 将 Set 转换回数组 - [...new Set([.
    【解决方案2】:

    您应该确保只添加不存在的元素,您可以使用数组上的includes 函数来检查这一点,并且您还需要确保保留所有以前的内容.

    一个潜在的解决方案可能是执行以下操作:

    const updateValue = (val) => {
      if (val === 'A' || val === 'B') {
        if(!filterTags.one.includes(val)) {
          setFilterTags((prev) => ({ one: [...prev.one, val], two: prev.two }));
        }
      } else {
        if(!filterTags.two.includes(val)) {
          setFilterTags((prev) => ({ one: prev.one, two: [...prev.two, val] }));
        }
      }
    };
    

    【讨论】:

      【解决方案3】:

      此注释代码可以帮助您:

      const updateValue = (val) => {
        //creating a temporary copy of filterTags
        const tempFilterTags = {...filterTags}
        //checking if val is A or B and if finterTag.one does not contain the value
        if ((val === 'A' || val === 'B') && filterTags.one.find(el=> el == val) === null) {
          //if success, push the value for field one and update filterTag
          tempFilterTags.one.push(val)
          setFilterTags(tempFilterTags)
        } 
        //checking if val is C, D, E of F and if finterTag.two does not contain the value
        if ((val === 'C' || val === 'D' || val === 'E' || val === 'F') && filterTags.two.find(el=> el == val) === null) {
          //if success, push the value for field two and update filterTag
          tempFilterTags.two.push(val)
          setFilterTags(tempFilterTags)
        } 
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-18
        • 2021-01-21
        • 1970-01-01
        • 2020-12-15
        • 1970-01-01
        • 2020-08-06
        • 2021-06-15
        • 1970-01-01
        相关资源
        最近更新 更多