我有一个简单的组件<StatefulView>,用于维护内部状态。我还有另一个组件<App>,用于切换是否<StatefulView>渲染。
<StatefulView>
<App>
不过,我想<StatefulView>在安装/卸载之间保持的内部状态。
我想我可以实例化该组件,<App>然后控制其是否被渲染/安装。
var StatefulView = React.createClass({ getInitialState: function() { return { count: 0 } }, inc: function() { this.setState({count: this.state.count+1}) }, render: function() { return ( <div> <button onClick={this.inc}>inc</button> <div>count:{this.state.count}</div> </div> ) } }); var App = React.createClass({ getInitialState: function() { return { show: true, component: <StatefulView/> } }, toggle: function() { this.setState({show: !this.state.show}) }, render: function() { var content = this.state.show ? this.state.component : false return ( <div> <button onClick={this.toggle}>toggle</button> {content} </div> ) } });
这显然不起作用,<StatefulView>每次切换时都会创建一个新的。
这是一个JSFiddle。
有没有办法在卸载后保留同一个组件以便重新安装它?
要在 React 中挂载和卸载之间保留组件的状态,您可以使用更高级的模式,包括使用键进行条件渲染或使用高阶组件 (HOC)。另一种方法是在更高级别管理状态并将其作为 props 传递下去。
以下是使用高阶组件(HOC)实现此目的的方法:
劉貉复制代码class StatefulView extends React.Component { constructor(props) { super(props); this.state = { count: 0, }; this.inc = this.inc.bind(this); } inc() { this.setState({ count: this.state.count + 1 }); } render() { return ( <div> <button onClick={this.inc}>inc</button> <div>count: {this.state.count}</div> </div> ); } }
StatefulView
劉貉复制代码function withPersistentState(WrappedComponent) { return class extends React.Component { constructor(props) { super(props); this.state = { instance: null, }; } componentDidMount() { const instance = this.state.instance || <WrappedComponent ref={(ref) => (this.wrappedInstance = ref)} />; this.setState({ instance }); } render() { return this.state.instance ? ( <div style={{ display: this.props.show ? 'block' : 'none' }}>{this.state.instance}</div> ) : null; } }; } const PersistentStatefulView = withPersistentState(StatefulView);
劉貉复制代码class App extends React.Component { constructor(props) { super(props); this.state = { show: true, }; this.toggle = this.toggle.bind(this); } toggle() { this.setState({ show: !this.state.show }); } render() { return ( <div> <button onClick={this.toggle}>toggle</button> <PersistentStatefulView show={this.state.show} /> </div> ); } } export default App;
withPersistentState
PersistentStatefulView
show
这种模式确保即使有条件地渲染,有状态组件的状态也能得到维持。