ReactJS 中的状态管理
State management in ReactJS
我正在构建一个地图相关组件,其中 center
zoom
features
等属性将由 props
推送到该组件。当地图组件挂载后,我会根据props
设置地图视图并添加一些功能。
当状态改变时,我不确定 componentWillReceiveProps
更新地图视图是否正确。
此外,当用户与地图交互时,地图视图会发生变化,这意味着地图组件的内部状态发生了变化,是否需要通过setState
更新状态以保持状态一致性?
对于initial rendering and initialisation
,可以将props
从父组件传给Map组件。
例如初始缩放、地理围栏、默认标记等
现在从这里开始,如果地图组件有任何变化,比如新标记,地理围栏,那么你应该manage local state at Map Component level and store the state internally with state
。如果 APP 需要有关此更改数据的一些信息,请执行 state lifting
.
在APP中,如果Map组件再次发生变化,比如重置Map Component,你应该使用componentWillReceiveProps
获取props,然后setState
渲染Map使用这些新重置 data.Now 再次组件,这些新传递的道具将保存在组件状态中。
为了详细说明之前的答案,混合局部状态和全局状态的技巧是:
- 尽可能保持本地化:任何给定状态项的范围越小,它给您带来的错误就越少。
- 必要时将状态传递到 parent(状态提升)
- 为 parent 传递影响您存储的本地状态的新状态做好准备。
这是一个演示如何完成的示例。我刚刚从 create-react-app
中获取了一个入门应用程序,并添加了一个带有缩放 属性 的 "Map" 组件作为示例。
App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import Map from './Map';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {zoom: 1.0}
this.handleZoomChange = this.handleZoomChange.bind(this);
}
handleZoomChange(zoom) {
this.setState( {zoom: zoom} );
}
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<p className="App-intro">
<Map zoom={this.state.zoom} onZoomChange={this.handleZoomChange}/>
</p>
</div>
);
}
}
export default App;
Map.js
import React, { Component } from 'react';
class Map extends Component {
constructor(props) {
super(props);
this.state = {zoom: this.props.zoom}
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
// Called when the parent wants us to re-render with
// new props. Note that the new props may be the same
// as the old ones.
componentWillReceiveProps(nextProps) {
if( nextProps.zoom ) {
this.setState( {zoom: nextProps.zoom } );
}
}
// User submits the form. Pass it up to our parent.
handleSubmit(e) {
e.preventDefault();
this.props.onZoomChange(this.state.zoom);
}
// Control the input field
handleChange(e) {
this.setState( {zoom: e.target.value} );
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="text" value={this.state.zoom} onChange={this.handleChange}/>
<button type="submit">Save</button>
</form>
);
}
};
export default Map;
所以你可以在这里看到缩放状态一直停留在地图组件中,直到用户按下保存按钮。那时,它被提升到 parent(App 组件),它将它保存在自己的状态中。然后调用 componentWillReceiveProps() 为 re-rendering 准备 Map 组件,并且 Map 组件再次更新其状态(在本例中为相同的值,但在其他情况下可能不同)。
我正在构建一个地图相关组件,其中 center
zoom
features
等属性将由 props
推送到该组件。当地图组件挂载后,我会根据props
设置地图视图并添加一些功能。
当状态改变时,我不确定 componentWillReceiveProps
更新地图视图是否正确。
此外,当用户与地图交互时,地图视图会发生变化,这意味着地图组件的内部状态发生了变化,是否需要通过setState
更新状态以保持状态一致性?
对于
initial rendering and initialisation
,可以将props
从父组件传给Map组件。例如初始缩放、地理围栏、默认标记等
现在从这里开始,如果地图组件有任何变化,比如新标记,地理围栏,那么你应该
manage local state at Map Component level and store the state internally with state
。如果 APP 需要有关此更改数据的一些信息,请执行state lifting
.在APP中,如果Map组件再次发生变化,比如重置Map Component,你应该使用
componentWillReceiveProps
获取props,然后setState
渲染Map使用这些新重置 data.Now 再次组件,这些新传递的道具将保存在组件状态中。
为了详细说明之前的答案,混合局部状态和全局状态的技巧是:
- 尽可能保持本地化:任何给定状态项的范围越小,它给您带来的错误就越少。
- 必要时将状态传递到 parent(状态提升)
- 为 parent 传递影响您存储的本地状态的新状态做好准备。
这是一个演示如何完成的示例。我刚刚从 create-react-app
中获取了一个入门应用程序,并添加了一个带有缩放 属性 的 "Map" 组件作为示例。
App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import Map from './Map';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {zoom: 1.0}
this.handleZoomChange = this.handleZoomChange.bind(this);
}
handleZoomChange(zoom) {
this.setState( {zoom: zoom} );
}
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<p className="App-intro">
<Map zoom={this.state.zoom} onZoomChange={this.handleZoomChange}/>
</p>
</div>
);
}
}
export default App;
Map.js
import React, { Component } from 'react';
class Map extends Component {
constructor(props) {
super(props);
this.state = {zoom: this.props.zoom}
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
// Called when the parent wants us to re-render with
// new props. Note that the new props may be the same
// as the old ones.
componentWillReceiveProps(nextProps) {
if( nextProps.zoom ) {
this.setState( {zoom: nextProps.zoom } );
}
}
// User submits the form. Pass it up to our parent.
handleSubmit(e) {
e.preventDefault();
this.props.onZoomChange(this.state.zoom);
}
// Control the input field
handleChange(e) {
this.setState( {zoom: e.target.value} );
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input type="text" value={this.state.zoom} onChange={this.handleChange}/>
<button type="submit">Save</button>
</form>
);
}
};
export default Map;
所以你可以在这里看到缩放状态一直停留在地图组件中,直到用户按下保存按钮。那时,它被提升到 parent(App 组件),它将它保存在自己的状态中。然后调用 componentWillReceiveProps() 为 re-rendering 准备 Map 组件,并且 Map 组件再次更新其状态(在本例中为相同的值,但在其他情况下可能不同)。