首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >更新Redux中嵌套状态的更简洁/更短的方法?

更新Redux中嵌套状态的更简洁/更短的方法?
EN

Stack Overflow用户
提问于 2016-02-24 02:20:34
回答 6查看 28.4K关注 0票数 33

有时减速机会变得很乱:

代码语言:javascript
复制
const initialState = {
    notificationBar: {
        open: false,
    },
};

export default function (state = initialState, action) {
  switch (action.type) {
    case actions.LAYOUT_NOTIFICATIONBAR_OPEN:
      return Object.assign({}, state, {
        // TODO: Find a cleaner way to do this!
        notificationBar: Object.assign({}, state.notificationBar, {
          open: true,
        }),
      });
    default:
      return state;
  }
}

有什么更简洁的方法吗?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2016-02-24 02:35:14

UPD:它现在是ES2018的一部分

它可能会通过一个然而属性扩展了语法略有改进。

代码语言:javascript
复制
return {
    ...state,
    notificationBar: {
        ...state.notificationBar,
        open: true,
    },
};
票数 58
EN

Stack Overflow用户

发布于 2016-02-24 02:56:20

虽然可以使用spread操作符,但是还有很多其他方法可以实现相同的结果,甚至不需要将来的JS编译器来实现非标准化的特性。以下是一些没有特定顺序的其他选项。

返回文字

如果您确信您的状态不会增长,那么只需将整个新状态作为文字返回即可。

代码语言:javascript
复制
return {
  notificationBar: {
    open: true
  }
}

然而,这并不经常是合适的,因为你的状态不太可能如此简单。

联合收割机

Redux为您提供了一个实用方法,用于组合几个在状态对象的不同部分上工作的还原器。在本例中,您将创建一个单独处理此对象的notificationBar还原器。

代码语言:javascript
复制
 createStore(combineReducers({
   notificationBar: function(state=initialNBarState, action) {
     switch (action.type) {
       case actions.LAYOUT_NOTIFICATIONBAR_OPEN:
         return Object.assign({}, state, { open: true });
   }
 });

这使您不必担心顶级属性,这样您就可以避免嵌套对Object.assign的调用。

如果您的状态在逻辑上可以分解为明确定义的部分,那么这可能是解决这个问题的最惯用的方法。

使用不可变数据

可以使用持久数据结构库创建数据结构,而不是修改以返回副本。

莫里

Mori是将Clojure的数据结构和functional编译成JS的结果。

代码语言:javascript
复制
import { hashMap, updateIn } from 'mori';

const initialState = hashMap(
  "notificationBar", hashMap(
    "open", false
  )
);

// ...

return updateIn(state, ['notificationBar', 'open'], true);

ImmutableJS

ImmutableJS是一种更必要的方法,可以将哈希数组映射的尝试的语义从Clojure的持久数据结构转移到Javascript。

代码语言:javascript
复制
import { Map } from 'immutable';

const initialState = Map({
  notificationBar: Map({
    open: true
  });
});

// ...

return state.setIn(['notificationBar', 'open'], true);

别名Object.assign

您可以创建一个更友好的Object.assign版本来编写上面代码的简洁版本。实际上,它几乎可以和...运算符一样简洁。

代码语言:javascript
复制
function $set(...objects) {
  return Object.assign({}, ...objects);
}

return $set(state, {
  notificationBar: $set(state.notificationBar, {
    open: true,
  })
});

使用不变的帮手

还有许多库也提供了对常规可变对象进行修改的不可变帮助程序。

更新

React在很长一段时间内都有一套不变的帮手。它们使用与MongoDB查询类似的语法。

代码语言:javascript
复制
import update from 'react-addons-update';

return update(state, {
  notificationBar: {
    open: { $set: true }
  }
});

道具不可变

此库允许您使用熟悉的点路径来指定(嵌套)属性的更新。

代码语言:javascript
复制
import dotProp from 'dot-prop-immutable';

return dotProp.set(state, 'notificationBar.open', true);

最新情况

这个库是react-addons-update的包装器,它为更新(嵌套)属性提供了更多的功能语法。

不是传递一个新值,而是传递一个接受旧值并返回新值的函数。

代码语言:javascript
复制
import updateIn from 'update-in';

return updateIn(state, ['notificationBar', 'open'], () => true);

不可变路径

对于更新属性,此库类似于dot-prop-immutableupdate-in之间的交叉。

代码语言:javascript
复制
import path from 'immutable-path';

return path.map(state, 'notificationBar.open', () => true);
票数 46
EN

Stack Overflow用户

发布于 2016-12-27 09:50:34

你可以用镜片。

代码语言:javascript
复制
import { set, makeLenses } from '@DrBoolean/lenses'

const L = makeLenses(['notificationBar', 'open']);
const notificationBarOpen = compose(L.notificationBar, L.open)
const setNotificationBarOpenTrue = set(notificationBarOpen, true)

const a = { notificationBar: { open: false } }
const b = setNotificationBarOpenTrue(a) 
// `a` is left unchanged and `b` is `{ notificationBar: { open: true } }`

您可以将镜头视为组合属性访问/更新。

关于镜片的一些好资源:

如果您可以阅读lisps,我也会建议您看看这个优秀的介绍的镜头球拍文档。最后,如果您想深入阅读haskell,您可以查看:镜片.组合数据存取和操作

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35592078

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档