简体   繁体   English

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

[英]JS spread operator workflow on React

React suggests not to mutate state. React 建议不要改变 state。 I have an array of objects which I am manipulating based on some events.我有一组对象,我正在根据一些事件进行操作。 My question is, is it okay to write it like this:我的问题是,这样写可以吗:

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

Am I mutating the original object by doing like above?我是否像上面那样改变了原来的 object ? Or does it make a difference if written like this:或者如果这样写会有所不同:

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

What's the preferred way to do this?这样做的首选方法是什么? Spread operators are getting a lot verbose and I am not liking it, but I prefer it if that's how I need to do it here.扩展运算符变得非常冗长,我不喜欢它,但如果我需要在这里这样做,我更喜欢它。 immutable.js and immer or not an option right now. immutable.js 和 immer 现在不是一个选项。

The first approach is mutating on the original object reference because you're not creating a deep clone.第一种方法是在原始 object 参考上进行变异,因为您没有创建深度克隆。

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

Here reference of copiedFilters[filter.id] and filters[filter.id] is same.这里对copiedFilters[filter.id]filters[filter.id]的引用是一样的。

Although this may work, the second approach is more correct since that way you create a new object reference when you use spread operator.虽然这可能有效,但第二种方法更正确,因为当您使用扩展运算符时,您会创建一个新的 object 引用。 With this approach open will be the updated value in copiedFilters but filters should still have the old value.使用这种方法open将是copiedFilters中的更新值,但filters仍应具有旧值。

You can create a deep clone when you copy but that would be waste of computation and memory, I don't think it's needed here.您可以在复制时创建深度克隆,但这会浪费计算和 memory,我认为这里不需要。

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

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