我正在使用 es6 类,我最终在我的顶级状态中使用了几个复杂的对象,并试图使我的主要组件更加模块化,所以我创建了一个简单的类包装器来保持顶级组件上的状态,但允许更多本地逻辑.
包装类将一个函数作为其构造函数,该函数在主组件状态上设置一个属性。
export default class StateWrapper {
constructor(setState, initialProps = []) {
this.setState = props => {
this.state = {...this.state, ...props}
setState(this.state)
}
this.props = initialProps
}
render() {
return(<div>render() not defined</div>)
}
component = props => {
this.props = {...this.props, ...props}
return this.render()
}
}
然后对于顶级状态的每个复杂属性,我创建一个 StateWrapped 类。您可以在此处在构造函数中设置默认道具,它们将在类初始化时设置,您可以参考本地状态的值并设置本地状态,参考本地函数,并将其传递到链上:
class WrappedFoo extends StateWrapper {
constructor(...props) {
super(...props)
this.state = {foo: "bar"}
}
render = () => <div onClick={this.props.onClick||this.onClick}>{this.state.foo}</div>
onClick = () => this.setState({foo: "baz"})
}
因此,我的顶级组件只需要构造函数将每个类设置为其顶级状态属性、简单的渲染以及任何跨组件通信的函数。
class TopComponent extends React.Component {
constructor(...props) {
super(...props)
this.foo = new WrappedFoo(
props => this.setState({
fooProps: props
})
)
this.foo2 = new WrappedFoo(
props => this.setState({
foo2Props: props
})
)
this.state = {
fooProps: this.foo.state,
foo2Props: this.foo.state,
}
}
render() {
return(
<div>
<this.foo.component onClick={this.onClickFoo} />
<this.foo2.component />
</div>
)
}
onClickFoo = () => this.foo2.setState({foo: "foo changed foo2!"})
}
似乎对我的目的来说工作得很好,请记住,尽管您不能更改分配给顶级组件的包装组件的属性的状态,因为每个包装组件都在跟踪自己的状态,但会更新顶级组件的状态每次它改变。