ReactJS 中的状态管理

IT技术 reactjs state-management
2021-05-05 07:58:33

我正在构建一个与地图相关的组件,其中类似的属性center zoom features将被推送到组件props当地图组件挂载后,我会设置地图视图,并根据props.

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

另外,当用户与地图交互时,地图视图会发生变化,这意味着地图组件的内部状态发生了变化,是否需要更新状态setState以保持状态一致性?

2个回答

为了详细说明前面的答案,混合局部状态和全局状态的技巧是:

  • 尽可能多地保持本地:任何给定状态项的范围越小,它给您带来的错误就越少。
  • 必要时将状态传递给父级(状态提升)
  • 准备好让父级传递影响您存储的本地状态的新状态。

这是一个演示如何完成此操作的示例。我刚刚从中获取了一个入门应用程序,create-react-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;

地图.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 组件内,直到用户按下 Save 按钮。在这一点上,它被提升到父级(App 组件),并将其保存在自己的状态中。然后调用 componentWillReceiveProps() 为 Map 组件准备重新渲染,Map 组件再次更新其状态(在本例中为相同的值,但在其他情况下可能不会)。

  1. 对于initial rendering and initialisation,可以将propsfrom 父组件传递给 Map 组件。

    例如初始缩放、地理围栏、默认标记等。

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

  3. 从 APP 中,如果 Map 组件再次发生更改,例如重置 Map 组件,您应该使用这些新的重置数据componentWillReceiveProps来检索 props 并setState重新渲染 Map 组件。现在,这些新传递的 props 将保存在组件状态.