我目前正在研究React JS和React本机框架。在中途,当我读到Facebook的Flux和Redux实现时,我遇到了不变性或不变性JS库
问题是,为什么不变性如此重要?变异对象有什么错?这不是让事情变得简单吗
给出一个例子,让我们考虑一个简单的新闻阅读器 app,打开屏幕是新闻标题的列表视图。
如果我将对象数组设置为,初始值为,则无法对其进行操作。这就是不变性原则所说的,对吗?(如果我错了,请纠正我。)
但是,如果我有一个必须更新的新新闻对象呢?在通常情况下,我可以将对象添加到数组中。
在这种情况下,我如何实现目标?是否删除存储并重新创建它?
向数组中添加对象不是一种成本较低的操作吗
我最近一直在研究同一个话题。我会尽我所能回答你的问题,并尝试分享到目前为止我所学到的东西
问题是,为什么不变性如此重要?这有什么问题吗
变异对象?这不是让事情变得简单吗
基本上,它归结为一个事实,即不变性增加了可预测性、性能(间接地),并允许进行突变跟踪
可预测性
突变隐藏了变化,这会产生(意想不到的)副作用,从而导致讨厌的bug。当您强制实施不变性时,您可以保持应用程序体系结构和心智模型的简单,从而更容易对应用程序进行推理
性能
即使向不可变对象添加值意味着需要创建一个新实例,其中需要复制现有值,并且需要向新对象添加新值,这会消耗内存,但不可变对象可以利用结构共享来减少内存开销
所有更新都返回新值,但内部结构共享给
大幅减少内存使用(和GC抖动)。这意味着如果
如果附加到一个包含1000个元素的向量,它实际上不会创建
一个新的向量1001个元素长。最有可能的是,内部只有几个
分配小对象
你可以在这里了解更多
突变跟踪
除了减少内存使用外,不变性还允许您通过使用引用和值相等来优化应用程序。这使我们很容易看到是否有任何变化。例如,react组件中的状态更改。您可以使用shouldComponentUpdate通过比较状态对象来检查状态是否相同,并防止不必要的渲染。
你可以在这里了解更多
额外资源:
- 不变性之道
- 不变的数据结构和JavaScript
- JavaScript中的不变性
如果我设置了一个数组,首先是一个值为的对象数组。我不能
操纵它。这就是不变性原理所说的,对吗
如果我错了,请告诉我。但是,如果我有一个新的新闻对象
要更新吗?在通常情况下,我可以将对象添加到
大堆在这种情况下,我如何实现目标?删除商店&;重现它?
向数组中添加对象不是一种成本较低的操作吗
是的,这是正确的。如果您对如何在应用程序中实现这一点感到困惑,我建议您了解redux是如何做到这一点的,以熟悉核心概念,这对我有很大帮助
我喜欢以Redux为例,因为它包含不变性。它有一个单一的不可变状态树(称为存储),其中所有状态更改都是通过调度操作显式进行的,这些操作由一个reducer处理,reducer接受上一个状态和所述操作(一次一个)并返回应用程序的下一个状态。你可以在这里阅读更多关于它的核心原则
在egghead.io上有一个很好的redux课程,redux的作者Dan Abramov将这些原则解释如下(为了更好地适应场景,我对代码进行了一些修改):
从“React”导入React;
从“react dom”导入react dom;
//减速器。
const news=(state=[],action)=>;{
开关(动作类型){
案例“添加新闻项目”:{
返回[…状态,action.newItem];
}
默认值:{
返回状态;
}
}
};
//商店。
常量createStore=(减速机)=>;{
让国家;
让侦听器=[];
const subscribe=(侦听器)=>{
listeners.push(listener);
返回()=>{
侦听器=侦听器.filter(cb=>;cb!==侦听器);
};
};
const getState=()=>;state;
常量调度=(操作)=>{
状态=减速器(状态、动作);
forEach(cb=>;cb());
};
调度({});
返回{subscribe,getState,dispatch};
};
//使用reducer初始化存储。
const store=createStore(新闻);
//组成部分。
const News=React.createClass({
onAddNewsItem(){
const{newsttitle}=this.refs;
仓库调度({
键入:“添加新闻项目”,
新闻项:{title:newsttitle.value}
});
},
render(){
const{news}=this.props;
返回(
<;div>;
<;输入ref=“newsttitle”/>;
<;button onClick={this.onAddNewsItem}>;添加<;/button>;
<;ul>;
{news.map(({title})=>;<;li>;{title}<;/li>;)}
<;/ul>;
<;/div>;
);
}
});
//存储分派时将执行的处理程序。
常量呈现=()=>;{
ReactDOM.render(
<;News News={store.getState()}/>;,
document.getElementById('news')
);
};
//入口点。
存储。订阅(呈现);
render();
此外,这些视频还进一步详细演示了如何实现以下方面的不变性:
- 阵列
- 物体