何时使用 componentWillReceiveProps 生命周期方法?

新手上路,请多包涵

我是 React/Redux 的新手,状态有问题。

轨迹容器.jsx

 class TrajectContainer extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            trajects: props.trajects,
            onClick: props.onClick
        };
    }

    componentWillReceiveProps(nextProps) {
        console.log('componentWillReceiveProps', nextProps);
        this.setState(nextProps);
    }

    render() {
        // When the componentWillReceiveProps is not present, the this.state will hold the old state
        console.log('rerender', this.state);
        return (<div className="col-md-6">
            <h2>Trajects</h2>
            <button className="btn btn-primary" onClick={this.state.onClick}>Add new Traject</button>
            {this.state.trajects.map(traject => <Traject traject={traject} key={traject.name}/>)}
        </div>)
    }
}

const mapStateToProps = function (store) {
    console.log('mapToStateProps', store);
    return {
        trajects: store.trajects
    };
};

const mapDispatchToProps = function (dispatch, ownProps) {
    return {
        onClick: function () {
            dispatch(addTraject());
        }
    }
};

export default connect(mapStateToProps, mapDispatchToProps)(TrajectContainer);

当 reducer 返回新状态时,组件将使用新数据重新渲染。

但是:如果我删除 componentWillReceiveProps 函数,则 render() 函数具有旧状态。

我检查了在 mapStateToProps 中收到的数据,这是新的新状态。所以我不明白为什么我需要 componentWillReceiveProps 函数才能让渲染函数接收新数据。

难道我做错了什么?

原文由 Mazzy 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 983
2 个回答

componentWillReceiveProps 如果你想用新的道具值更新状态值是必需的,只要道具值发生任何变化,这个方法就会被调用。


在您的情况下,为什么需要此 componentWillReceiveProps 方法?

因为您将道具值存储在状态变量中,并像这样使用它:

this.state.KeyName

这就是为什么你需要 componentWillReceiveProps 生命周期方法来用新的 props 值更新状态值,只有组件的 props 值会被更新,但 状态不会自动更新。如果您不更新状态,那么 this.state 将始终具有初始数据。

componentWillReceiveProps 如果您不将 props 值存储在 state 中并直接使用,则不需要:

this.props.keyName

现在 react 将始终在 render 方法中使用更新的 props 值,如果 props 发生任何变化,它将使用新的 props 重新渲染组件。

根据 文档

componentWillReceiveProps() 在挂载的组件收到新的 props 之前被调用。如果您需要更新状态以响应 prop 更改(例如,重置它),您可以比较 this.props 和 nextProps 并在此方法中使用 this.setState() 执行状态转换。

React 在挂载期间不会使用初始道具调用 componentWillReceiveProps。如果组件的某些道具可能会更新,它只会调用此方法。

建议:

不要将 props 值存储在 state 中,直接使用 this.props 并创建 ui 组件。

原文由 Mayank Shukla 发布,翻译遵循 CC BY-SA 3.0 许可协议

更新

componentDidUpdate()

现在应该使用而不是 componentWillReceiveProps

另请参阅 gaearon 的一篇文章 re writing resilient components

这里有两个潜在的问题

  1. 不要重新分配你的道具来说明你正在使用 redux 从商店中提取值并将它们作为道具返回给你的组件

避免状态意味着您不再需要构造函数或生命周期方法。因此,您的组件可以编写为无状态功能组件,以这种方式编写组件具有性能优势。

  1. 如果您传递的是 mapDispatchahToProps,则无需将操作包装在 dispatch 中。如果传递了一个对象,则假定其中的每个函数都是一个动作创建者。一个具有相同函数名称的对象,但每个动作创建者都被包装到一个分派中,将被返回

下面是一个代码片段,它从您的组件中删除状态并依赖于从 redux 存储返回的状态

 import React from "react";
import { connect } from "react-redux";

const TrajectContainer = ({ trajects, addTraject }) => (
	<div className="col-md-6">
		<h2>Trajects</h2>
		<button className="btn btn-primary" onClick={addTraject}>Add new Traject</button>
		{trajects.map(traject => <Traject traject={traject} key={traject.name} />)}
	</div>
);

const mapStateToProps = ({ trajects }) => ({ trajects });

export default connect( mapStateToProps, { addTraject })(TrajectContainer);

原文由 user1095118 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进