摘要:目的是为了解决在重用的时候,持久和方法重用的问题。换句话说你不用担心把组件写成模式不好重用,如果你需要传统的方式使用,一下即可。
这篇文章所述的思想最终进化成了一个简单的状态管理模式,称React StateUp Pattern,详细介绍请参阅:https://segmentfault.com/a/11...
写了一个非常简单的实验性Pattern,暂且称为PurifiedComponent。目的是为了解决React Component在重用的时候,state持久和方法重用的问题。
React组件和state的生命周期不一致,即使是在一个对话框内,也可能因为折叠或者平移,一些组件消失但是他们的state还需要持久;这种情况下在this.state内存放状态并不能解决问题,因为如果这个组件在渲染时消失了,它的state也没了;
React官方的说法是应该把state写到相关组件的共同祖先上去,这一点在实现逻辑上本身没有问题,有问题的地方是重用很不方便;很多view state,例如和输入框配合的校验函数或者出错信息,他们本身就应该是和组件一起使用的,离开组件去多带带维护没有意义;
解决这个问题的思路是,把组件需要的view state独立构建对象;持久化state的责任,托管到父组件去,但是对组件操作的责任,仍然留在子组件内,换句话说,子组件和它的state是由父组件bind在一起的。
class PurifiedComponent extends React.PureComponent { setState(props) { let { state, name, setState } = this.props setState({ [name] : Object.assign(new state.constructor(), state, props) }) } } class Impure extends React.Component { constructor(props) { super() this.state = { state: new props.component.State() } } render() { let Component = this.props.component return} }
上面的两个class是基础类;PurifiedComponent在React.PureComponent基础上实现了一个setState方法。
使用方式看下面的例子,Child1是一个独立PurifiedComponent的例子,Composite是组合的例子;
继承自PurifiedComponent的类需要提供一个静态类变量State,它是一个class;这个类是用于描述状态的类,即所谓的view state;它也应该具有行为,尤其是那些计算computed的方法,对父组件来说可以直接访问;
PurifiedComponent不在类结构内维护state,即不使用this.state;创建和保存它的state是它的父容器的职责;父容器可以通过new Child1.State()创建这个state;这是第一个约定;
第二个约定是,这些类需要有三个props:
state,从外部传入的state;
name,state在父容器组件的state内的property name;
setState,父容器的setState方法;
有了这三者后,子组件就可以做stateful的工作,用传入的state和setState工作;name原则来说不是逻辑需要的,但可以结合PureComponent避免不必要的刷新。
class Child1 extends PurifiedComponent { static State = class State { constructor() { this.label = "" } } render() { let {state, name} = this.props console.log(`render ${name}`) return () } }
Composite是一个组合,目前没有设计使用数组组合的方式,只看看用Property Name来组合的办法,这个Composite和它的子组件一样没有使用自己的this.state,这显示了这种Pattern是可以自下而上组成树的;
Composite的构造函数里有一个this.ssb,它表示的是bound函数,之所以在对象上创建是为了保持它的引用稳定,这样在向child传递三个参数时,setState和name都是恒定的,只有第一个state变化时子组件会重新渲染;这是我们需要的特性;
class Composite extends PurifiedComponent { static State = class State { constructor() { this.child1 = new Child1.State() this.child2 = new Child1.State() } } constructor() { super() this.ssb = this.setState.bind(this) } render() { return () } } class App extends Component { render() { return} } export default App
最后的Impure是一键拦截这种层层向上提升state holder的行为,它可以作为一个stateful的组件,用它的this.state来装载所有内含的PurifiedComponent构成的树。换句话说你不用担心把组件写成Purified模式不好重用,如果你需要传统的方式使用,Impure一下即可。
上述代码虽然简单但是可以工作,我会在生产环境中尝试一下。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/88168.html
摘要:一般这种情况会在类的构造函数内创建一个属性,引用或词法域的,但后面会看到我们有更好的办法,避免这种手工代码。 换句话说,StateUp模式把面向对象的设计方法应用到了状态对象的管理上,在遵循React的组件化机制和基于props实现组件通讯方式的前提之下做到了这一点。 ---- 少妇白洁 阅读本文之前,请确定你读过React的官方文档中关于Lifting State Up的论述: ht...
摘要:本文用于阐述模式的算法和数学背景,以及解释了它为什么是里最完美的状态管理实现。欢迎大家讨论和发表意见。 本文用于阐述StateUp模式的算法和数学背景,以及解释了它为什么是React里最完美的状态管理实现。 关于StateUp模式请参阅:https://segmentfault.com/a/11... P-State, V-State 如果要做组件的态封装,从组件内部看,存在两种不同的...
摘要:匿名函数是我们喜欢的一个重要原因,也是,它们分别消除了很多代码细节上需要命名变量名或函数名的需要。这个匿名函数内,有更多的操作,根据的结果针对目录和文件做了不同处理,而且有递归。 能和微博上的 @响马 (fibjs作者)掰扯这个问题是我的荣幸。 事情缘起于知乎上的一个热贴,诸神都发表了意见: https://www.zhihu.com/questio... 这一篇不是要说明白什么是as...
摘要:的科学定义是或者,它的标志性原语是。能解决一类对语言的实现来说特别无力的状态机模型流程即状态。容易实现是需要和的一个重要原因。 前面写了一篇,写的很粗,这篇讲讲一些细节。实际上Fiber/Coroutine vs Async/Await之争不是一个简单的continuation如何实现的问题,而是两个完全不同的problem和solution domain。 Event Model 我...
摘要:我们已经回答了的构造函数和原型都是谁的问题,现在牵扯出来一个,我们继续检查的构造函数是全局对象上属性叫的对象的原型是个匿名函数,按照关于构造函数的约定,它应该是构造函数的属性我们给这个对象起个名字,叫。 我不确定JavaScript语言是否应该被称为Object-Oriented,因为Object Oriented是一组语言特性、编程模式、和设计与工程方法的笼统称谓,没有一个详尽和大家...
阅读 3071·2021-11-25 09:43
阅读 2251·2021-09-07 10:28
阅读 3542·2021-08-11 11:14
阅读 2776·2019-08-30 13:49
阅读 3543·2019-08-29 18:41
阅读 1161·2019-08-29 11:26
阅读 1975·2019-08-26 13:23
阅读 3371·2019-08-26 10:43