React 组件生命周期 componentWillReceiveProps 弃用导致 Redux 出现问题

React component lifecycle componentWillReceiveProps deprecation causes problem with Redux

我有 2 个组件,一个用于将新 post 添加到 post 数组,另一个组件映射到 post 数组并列出它们在页面上。

我想用 unshift() 将新的 post 添加到数组的顶部,但是自从 componentWillReceiveProps 被弃用以来,我一直在努力寻找解决方案新的 getDerivedStateFromProps 方法。


这里是Postform.js:

import React, { Component } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import { createPost } from "../actions/postActions";

class PostForm extends Component {
  constructor(props) {
    super(props);
    this.state = {
      title: "",
      body: "",
    };

    this.onChange = this.onChange.bind(this); // Bind onChange event
    this.onSubmit = this.onSubmit.bind(this); // Bind onSubmit event
  }

  // Set state when changing input value
  onChange(e) {
    this.setState({ [e.target.name]: e.target.value });
  }

  onSubmit(e) {
    e.preventDefault();

    const post = {
      title: this.state.title,
      body: this.state.body,
    };

    this.props.createPost(post);
  }

  render() {
    return (
      <div>
        <h1>Add Post</h1>
        <form onSubmit={this.onSubmit}>
          <div>
            <label>Title: </label>
            <br />
            <input
              type="text"
              name="title"
              onChange={this.onChange}
              value={this.state.title}
            />
          </div>
          <br />
          <div>
            <label>Body: </label>
            <br />
            <textarea
              name="body"
              onChange={this.onChange}
              value={this.state.body}
            />
          </div>
          <br />
          <button type="submit">Submit</button>
        </form>
      </div>
    );
  }
}

PostForm.propTypes = {
  createPost: PropTypes.func.isRequired,
};

export default connect(null, { createPost })(PostForm);

这里是Posts.js:

import React, { Component } from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { fetchPosts } from "../actions/postActions";

class Posts extends Component {
  state = {
    newPost: this.props.newPost,
  };

  componentDidMount() {
    this.props.fetchPosts();
  }

  // The new way I am struggling with
  static getDerivedStateFromProps(props, state) {
    if (props.newPost !== state.newPost) {
      props.posts.unshift(props.newPost);
    }
    return null;
  }

   // The old way, now renamed with UNSAFE_ prefix
  /* UNSAFE_componentWillReceiveProps(nextProps) {
    if (nextProps.newPost) {
      this.props.posts.unshift(nextProps.newPost);
    }
  } */

  render() {
    const postItems = this.props.posts.map((post) => (
      <div key={post.id + Math.random()}>
        <h3>{post.title}</h3>
        <p>{post.body}</p>
      </div>
    ));

    return (
      <div>
        <h1>Posts</h1>
        {postItems}
      </div>
    );
  }
}

Posts.propTypes = {
  fetchPosts: PropTypes.func.isRequired,
  posts: PropTypes.array.isRequired,
  newPost: PropTypes.object,
};

const mapStateToProps = (state) => ({
  posts: state.posts.items,
  newPost: state.posts.item,
});

export default connect(mapStateToProps, { fetchPosts })(Posts);


问题是 getDerivedStateFromProps 被调用了两次(初始挂载和每次渲染),

与只调用一次的 componentWillReceiveProps 不同。

这导致 newPost 被添加到数组中两次,因此它在页面上也显示为双倍。


我在这里使用 Redux,所以状态应该在商店中(大部分是),但我已经为 Posts.js 组件添加了一个状态,因为 getDerivedStateFromProps 否则不会工作(据我所试)。


简而言之:如何将 newPost 添加到 getDerivedStateFromProps(或其他生命周期方法)内的 props-array 而不会得到双重结果?

getDerivedStateFromProps 在调用 render 方法之前调用,在初始安装和后续更新时都是如此。根据反应文档,它应该 return 一个对象来更新状态,或者 null 不更新任何内容:https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops

您似乎已经在使用 redux,因此,一旦您完成了 createPost,为什么不在更新 Redux Store 中的 post 时执行 array.unshift,这样您的商店将保留state.posts.items 最新的 post 在最上面。