React 上的 JS 扩展运算符工作流程

问题描述 投票:0回答:1

React 建议不要改变状态。我有一组对象,我根据一些事件来操作它们。我的问题是,这样写可以吗:

const makeCopy = (arr) => arr.map((item) => ({ ...item }));

function SomeComponenet() {
    const [filters, setFilters] = useState(aemFilterData);

    const handleFilterClick = (filter, c) => {
        let copiedFilters = makeCopy(filters);

        /**
         * Apply toggle on the parent as well
         */
        if (!("parentId" in filter)) {
            copiedFilters[filter.id].open = !copiedFilters[filter.id].open;
        }
        setFilters(copiedFilters);
    }
}

我是否通过像上面那样改变原始对象?或者如果这样写会有什么不同吗:

const makeCopy = (arr) => arr.map((item) => ({ ...item }));

function SomeComponent() {
    const [filters, setFilters] = useState(aemFilterData);

    const handleFilterClick = (filter, c) => {
        let copiedFilters = makeCopy(filters);

        /**
         * Apply toggle on the parent as well
         */
        if (!("parentId" in filter)) {
            copiedFilters = copiedFilters.map((f) => {
            if (filter.id === f.id) {
              return {
                ...f,
                open: !f.open,
              };
            } else {
              return { ...f };
            }
          });
        }
        setFilters(copiedFilters);
    }
}

执行此操作的首选方法是什么?扩展运算符变得非常冗长,我不喜欢它,但如果我需要在这里这样做,我更喜欢它。 immutable.js 和 immer 或现在不是一个选项。

javascript reactjs immutability spread-syntax
1个回答
1
投票
const makeCopy = (arr) => arr.map((item) => item );

使用上面的代码,它会在原始对象引用上发生变化,因为我们没有创建深度克隆。

copiedFilters[filter.id].open = !copiedFilters[filter.id].open;

这里

copiedFilters[filter.id]
filters[filter.id]
的参考是一样的。

带有扩展运算符

const makeCopy = (arr) => arr.map((item) => ({ ...item }));

在这里我们也创建了内部对象的一个新副本。所以

copiedFilters[filter.id]
filters[filter.id]
会有不同的参考。

这与您的第二种方法相同。

因此,您可以在制作副本时使用扩展运算符,也可以跳过第二种方法中的副本并直接映射到

filters
,因为您在那里使用扩展运算符。这看起来更好,因为为什么运行循环两次 - 首先创建副本,然后更新
open

// let copiedFilters = makeCopy(filters); Not needed in second approach
copiedFilters = copiedFilters.map((f) => {
  if (filter.id === f.id) {
    return {
      ...f,
      open: !f.open,
    };
  } else {
    return { ...f };
  }
});

您可以在复制时创建深度克隆,但这会浪费计算和内存,我认为这里不需要它。 当您在对象中进一步嵌套时,深度克隆会很有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.