这篇文章所述的头脑终究进化成了一个简朴的状况管理形式,称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 <Component state={this.state.state} setState={this.setState.bind(this)} name="state" />
}
}
上面的两个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 (
<div>
<button
style={{width: 64, height: 24}}
onClick={() => this.setState({ label: state.label + 'a' })}
>{state.label}</button>
</div>
)
}
}
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 (
<div>
<Child1 state={this.props.state.child1} setState={this.ssb} name="child1" />
<Child1 state={this.props.state.child2} setState={this.ssb} name="child2" />
</div>
)
}
}
class App extends Component {
render() {
return <Impure component={Composite} />
}
}
export default App
末了的Impure
是一键阻拦这类层层向上提拔state holder的行动,它能够作为一个stateful的组件,用它的this.state
来装载一切内含的PurifiedComponent组成的树。换句话说你不必忧郁把组件写成Purified形式不好重用,假如你须要传统的体式格局运用,Impure一下即可。
上述代码虽然简朴然则能够事情,我会在临盆环境中尝试一下。