ReactJS中的国家管理

时间:2018-03-31 02:51:09

标签: reactjs state-management

我正在构建一个与地图相关的组件,其中center zoom features等属性将被props推送到组件。安装地图组件后,我将根据props设置地图视图并添加一些功能。

当状态发生变化时,我不确定componentWillReceiveProps更新地图视图是否正确。

此外,当用户与地图互动时,地图视图将发生变化,这意味着地图组件的内部状态已经发生变化,是否有必要通过setState更新状态以保持状态一致性?

2 个答案:

答案 0 :(得分:3)

要详细说明上一个答案,混合本地状态和全局状态的技巧是:

  • 保持尽可能多的本地:任何给定状态项的范围越小,它将导致您的错误越少。
  • 必要时将状态传递给父母(状态解除)
  • 为父母做好准备,传递影响存储的本地状态的新状态。

这是一个演示如何完成此操作的示例。我刚刚从create-react-app采用了一个入门应用,并添加了一个带有缩放属性的“地图”组件作为示例。

<强> 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;

因此,您可以在此处看到缩放状态保持在Map组件中,直到用户按下“保存”按钮。此时,它被提升到父(App组件),从而将其保存在自己的状态中。然后调用componentWillReceiveProps()来准备Map组件以进行重新渲染,并且Map组件再次更新其状态(在这种情况下为相同的值,但在其他情况下可能不会)。

答案 1 :(得分:1)

  1. 对于initial rendering and initialisation,可以将props从父组件传递到地图组件。

    e.g。初始缩放,地理围栏,默认标记等。

  2. 现在从这里开始,如果Map组件有任何变化,比如新标记,地理围栏那么你应该manage local state at Map Component level and store the state internally with state。如果APP需要有关此更改数据的一些信息,请执行state lifting

  3. 从APP,如果地图组件再次发生变化,例如重置地图组件,您应该使用componentWillReceiveProps来检索道具,并setState再次使用这些来渲染地图组件新的重置数据。现在,这些新传递的道具将以组件状态保存。