无法在道具或状态更改时更新组件
Cannot update component on props or state change
如果 showEdit
为真(参见 MessageReducer.js
中的 initState
)并且 CreateMessage
component if showEdit
is false 但我的代码不起作用。我的应用没有注意到 Dashboard.js
中的状态或道具变化。
我尝试在 Dashboard.js
中包含 this.setState
方法,但出现错误:"Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate"。
我也试过把showTypeForm
的值直接赋值给props输出(见Dashboard.js
中的注释)但是这个方法也没有用。我不确定要使用哪种生命周期方法。
我的代码如下所示。
MessageSummary.js:
import React, { Component } from 'react';
import { connect } from 'react-redux';
class MessageSummary extends Component {
editClick = (e) => {
e.preventDefault();
this.props.editMessage('123', 'I love web development'); //test values
}
render() {
return (
<button className="edit-message" onClick={this.editClick}>Edit
Message</button> // this button changes showEdit in MessageReducer.js
)
}
}
const mapDispatchToProps = (dispatch) => {
return {
editMessage: (id, newMessage) => dispatch(editMessage(id, newMessage))
}
}
export default connect(null, mapDispatchToProps)(MessageSummary);
MessageActions.js:
export const editMessage = (id, newMessage) => {
return (dispatch, getState, { getFirebase, getFirestore }) => {
dispatch({
type: "EDIT_MESSAGE"
});
}
}
RootReducer.js:
// importing everything
const rootReducer = combineReducers({
message: messageReducer
});
export default rootReducer;
MessageReducer.js:
const initState = {
showEdit: false
};
const messageReducer = (state = initState, action) => {
switch (action.type) {
case 'EDIT_MESSAGE':
initState.showEdit = !initState.showEdit; // toggling showEdit
return state;
default:
return state;
}
}
export default messageReducer;
Dashboard.js:
// importing everything
class Dashboard extends Component {
state = {
showEdit: this.props.message.showEdit
}
render() {
const { message } = this.props; // destructuring
// this.setState({
// showEdit: message.showEdit
// })
// const showTypeForm = message.showEdit ? <EditMessage /> : <CreateMessage />;
return (
<div className="message-form">
{this.state.showEdit ? <EditMessage /> : <CreateMessage />}
// {showTypeForm }
</div>
)
}
const mapStateToProps = (state) => {
return {
message: state.message
}
}
}
export default connect(mapStateToProps)(Dashboard);
你没有在 props 改变时更新状态,你需要在 componentDidUpdate 中执行此操作,并且有一个条件,这样它就不会陷入无限循环(“超出最大更新深度”)。我希望这会有所帮助。
在 render 中写入 this.setState 会使您陷入无限循环,原因是每当状态更改组件再次呈现时。
class Dashboard extends Component {
state = {
showEdit: this.props.message.showEdit
}
componentDidUpdate(prevProps){
if(this.props.message !== prevProps.message){
this.setState({
showEdit: this.props.message.showEdit
})
}
}
render() {
const { message } = this.props; // destructuring
// this.setState({
// showEdit: message.showEdit
// })
// const showTypeForm = message.showEdit ? <EditMessage /> : <CreateMessage />;
return (
<div className="message-form">
{this.state.showEdit ? <EditMessage /> : <CreateMessage />}
// {showTypeForm }
</div>
)
}
const mapStateToProps = (state) => {
return {
message: state.message
}
}
}
export default connect(mapStateToProps)(Dashboard);
你的减速器有问题 'MessageReducer.js'。在这里,您直接改变了违反 reducer 函数规范的 'initState' 值。它应该是一个纯函数并且不应该改变状态,每次它应该 return 一个新的状态对象。
请在 MessageReducer.js
中尝试使用以下更新代码
const initState = {
showEdit: false
};
const messageReducer = (state = initState, action) => {
switch (action.type) {
case 'EDIT_MESSAGE':
let updatedState = Object.assign({},state,{showEdit:!state.showEdit}) ;
return updatedState;
default:
return state;`enter code here`
}
}
export default messageReducer;
如果 showEdit
为真(参见 MessageReducer.js
中的 initState
)并且 CreateMessage
component if showEdit
is false 但我的代码不起作用。我的应用没有注意到 Dashboard.js
中的状态或道具变化。
我尝试在 Dashboard.js
中包含 this.setState
方法,但出现错误:"Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate"。
我也试过把showTypeForm
的值直接赋值给props输出(见Dashboard.js
中的注释)但是这个方法也没有用。我不确定要使用哪种生命周期方法。
我的代码如下所示。 MessageSummary.js:
import React, { Component } from 'react';
import { connect } from 'react-redux';
class MessageSummary extends Component {
editClick = (e) => {
e.preventDefault();
this.props.editMessage('123', 'I love web development'); //test values
}
render() {
return (
<button className="edit-message" onClick={this.editClick}>Edit
Message</button> // this button changes showEdit in MessageReducer.js
)
}
}
const mapDispatchToProps = (dispatch) => {
return {
editMessage: (id, newMessage) => dispatch(editMessage(id, newMessage))
}
}
export default connect(null, mapDispatchToProps)(MessageSummary);
MessageActions.js:
export const editMessage = (id, newMessage) => {
return (dispatch, getState, { getFirebase, getFirestore }) => {
dispatch({
type: "EDIT_MESSAGE"
});
}
}
RootReducer.js:
// importing everything
const rootReducer = combineReducers({
message: messageReducer
});
export default rootReducer;
MessageReducer.js:
const initState = {
showEdit: false
};
const messageReducer = (state = initState, action) => {
switch (action.type) {
case 'EDIT_MESSAGE':
initState.showEdit = !initState.showEdit; // toggling showEdit
return state;
default:
return state;
}
}
export default messageReducer;
Dashboard.js:
// importing everything
class Dashboard extends Component {
state = {
showEdit: this.props.message.showEdit
}
render() {
const { message } = this.props; // destructuring
// this.setState({
// showEdit: message.showEdit
// })
// const showTypeForm = message.showEdit ? <EditMessage /> : <CreateMessage />;
return (
<div className="message-form">
{this.state.showEdit ? <EditMessage /> : <CreateMessage />}
// {showTypeForm }
</div>
)
}
const mapStateToProps = (state) => {
return {
message: state.message
}
}
}
export default connect(mapStateToProps)(Dashboard);
你没有在 props 改变时更新状态,你需要在 componentDidUpdate 中执行此操作,并且有一个条件,这样它就不会陷入无限循环(“超出最大更新深度”)。我希望这会有所帮助。
在 render 中写入 this.setState 会使您陷入无限循环,原因是每当状态更改组件再次呈现时。
class Dashboard extends Component {
state = {
showEdit: this.props.message.showEdit
}
componentDidUpdate(prevProps){
if(this.props.message !== prevProps.message){
this.setState({
showEdit: this.props.message.showEdit
})
}
}
render() {
const { message } = this.props; // destructuring
// this.setState({
// showEdit: message.showEdit
// })
// const showTypeForm = message.showEdit ? <EditMessage /> : <CreateMessage />;
return (
<div className="message-form">
{this.state.showEdit ? <EditMessage /> : <CreateMessage />}
// {showTypeForm }
</div>
)
}
const mapStateToProps = (state) => {
return {
message: state.message
}
}
}
export default connect(mapStateToProps)(Dashboard);
你的减速器有问题 'MessageReducer.js'。在这里,您直接改变了违反 reducer 函数规范的 'initState' 值。它应该是一个纯函数并且不应该改变状态,每次它应该 return 一个新的状态对象。
请在 MessageReducer.js
const initState = {
showEdit: false
};
const messageReducer = (state = initState, action) => {
switch (action.type) {
case 'EDIT_MESSAGE':
let updatedState = Object.assign({},state,{showEdit:!state.showEdit}) ;
return updatedState;
default:
return state;`enter code here`
}
}
export default messageReducer;