使用 React Central State 简化您的应用
React-central-state是一个易于使用的 React 库,旨在帮助你在组件之间共享公共状态,无需将状态传递给 props,并最大限度地减少重新渲染。它已在 npm 和 GitHub 上发布。
如果您不想处理 redux/mobx 的复杂性,或者您的应用程序规模不够大,不足以使用这些工具,我建议采用一种不同的、更简单的方法:
import React from 'react';
import {CSComponent} from 'react-central-state';
class _Component1 extends React.Component {
...
changeFoo(value){
this.setCentralState({foo:value});
}
...
}
class _Component2 extends React.Component {
...
updateWith(){
return ['foo','someOtherProperty','anotherOne'];
}
render(){
let foo = this.centralState.foo || "Nothing here";
return <div>{foo}</div>
}
}
export const Component1 = CSComponent(_Component1);
export const Component2 = CSComponent(_Component2);
为什么要使用它
-
使用方便,几乎不需要额外的代码。
-
语法与原生 React 状态管理非常相似。
-
它允许所有组件从一个中央状态读取和更新。
-
你可以将它与 React 的普通状态一起使用。
-
让您可以控制触发组件更新的条件。
-
仅在需要时才触发重新渲染。
当状态发生变化时……
-
每个组件只订阅它感兴趣的中心状态属性的变化。
-
组件会根据挂载顺序收到通知。`shouldComponentUpdate`
方法会注入 `nextCentralState` 作为第三个参数,返回 `false` 将避免重新渲染——也就是默认行为。
工作原理
该存储系统保存着 CSComponents 的挂载顺序信息。当其状态发生变化时,更新会按顺序分发给至少监听到一个已更改属性的组件。
Redux 通过每个组件属性映射相关的“子状态”来实现这一点,而中央状态则要求你声明所有更改时需要重新渲染的属性。
这种有序分发还可以避免因所有者组件使子组件重新渲染或回调内部状态更改而导致的重复渲染调用。
缺点
-
在 render() 中访问 updateWith() 未返回的中心状态属性可能会导致“脏”的 DOM 元素——即与应用程序状态不同步。
-
另一方面,如果从 `updateWith()` 返回的属性键在 `render()` 中没有被访问,则很可能会导致不必要的重新渲染。
最终,你只需要注意 `render()` 需要更新哪些属性即可。
如何使用它
你只需要对代码做两处修改:
-
使用 CSComponent 包装导出的组件。
-
在包装组件的方法中实现 updateWith(),并返回一个中心状态属性数组,当值发生变化时,该数组会通知组件进行更新。
中央政府的更新和阅读:
与原生 React 类似,可以使用 `this.setCentralState()` 来更新和读取 `this.centralState` 属性。
你还可以注册一些函数,以便在 React 组件重新渲染之前,当一个或多个属性发生变化时调用这些函数:
import React from 'react';
import {CSComponent} from 'react-central-state';
class Display extends React.Component {
constructor(props){
super(props);
//Register listener for 'foo' object changes
this.fooListener = this.addCentralStateListener(prevstate=>{
alert("Foo changing from "+prevstate.foo+" to "+this.centralState.foo);
},'foo');
}
//Dont forget to remove the listener on unmounting
componentWillUnmount(){
this.removeCentralStateListener(this.fooListener);
}
updateWith(){return ['foo']};
//Re-render occurs after this.fooListener is called.
render(){
return <div>{this.centralState.foo}</div>
}
}
export default CSComponent(Display);
后续步骤
- 当从同一个回调/事件处理程序执行更新时,对更新进行某种批量处理。
如果你觉得我列出的优点大于缺点,那就去试试吧。
另外,我很想知道你的想法,如果你发现任何问题/错误,请在GitHub上报告。
文章来源:https://dev.to/greenstage/using-react-central-state-to-simplify-your-app--5f44