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 在最上面。
我有 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 在最上面。