将状态设置为值

时间:2019-10-15 15:55:37

标签: reactjs react-redux

我正在编写注册组件,并根据服务器使用Redux的响应在componentDidUpdate中设置错误,但是在提交后,状态会在几秒钟后(即在将错误消息设置为状态,它又被设置为空。

state = {
    firstName: "",
    lastName: "",
    email: "",
    password: ""
    msg: null,   
};  

componentDidUpdate(prevProps) {
    const { error } = this.props;

    if (error !== prevProps.error) {
        // check for register error
        if (error.id === "REGISTER_FAIL") {
            this.setState({ msg: error.msg.message });
        } else {
            this.setState({ msg: "null" });
        }
    }
}

render() {
    console.log(this.state)
}

我希望在this.state.msg中收到错误消息,但是当错误道具中存在错误时,我会得到一个空的this.state.msg

2 个答案:

答案 0 :(得分:0)

当您从setState调用componentDidUpdate时,组件将立即重新呈现。如果您没有在setState条件下调用else,就可以了。我相信正在发生的事情是您正在设置错误,组件已重新渲染,并且您的else条件重置了该消息。通过检查以下内容的输出来验证这一点:

componentDidUpdate(prevProps) { 
  const { error } = this.props;
  if (error !== prevProps.error) {
    // check for register error
    if (error.id === "REGISTER_FAIL") {
      this.setState({ msg: error.msg.message });
      console.log('if');
    } else {
      this.setState({ msg: null });
      console.log('else');
    }
  }
}

如果两者都在射击。那将确认您的问题。

来自docs

  

您可以在componentDidUpdate()中立即调用setState(),但请注意,必须将其包装在如上例中所示的条件下,否则会导致无限循环。这也将导致额外的重新渲染,这虽然对用户不可见,但会影响组件的性能。如果您要“镜像”某个状态来支持来自上方的道具,请考虑直接使用道具。进一步了解why copying props into state causes bugs

答案 1 :(得分:0)

我认为处理此类情况并避免重新渲染/无限循环的最佳方法是使用react生命周期的getDerivedStateFromProps方法进行处理。

state = {
    firstName: "",
    lastName: "",
    email: "",
    password: ""
    msg: null,
    prevPropMsg: null // we don't need this state, we can re-use msg state if you are not mutating msg state apart from in getDerivedStateFromProps method
};  

static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.error !== prevState.prevPropMsg) {
        // check for register error
        if (nextProps.error.id === "REGISTER_FAIL") {
            return { 
               msg: nextProps.error.msg.message,
               prevPropMsg: nextProps.error.msg.message
            };
        } else {
            return { 
               msg: null,
               prevPropMsg: null
            };
        }
    }

    return null;
}

render() {
    console.log(this.state)
}