【问题标题】:How to run onSubmit={} only after the props have updated?如何仅在道具更新后运行 onSubmit={} ?
【发布时间】:2019-04-22 11:47:38
【问题描述】:

我只想在我从减速器更新收到的道具之后在我的表单上运行 onSubmit。

const mapStateToProps = state => {
  return {
    authError: state.auth.authError  // I want this to update before the action.
  };
};

如果我在 onSutmit 处理程序中使用 console.log authError,我会收到旧的 authError。第二次运行时,我收到更新的 authError。

  handleSubmit = e => {
    e.preventDefault();
    console.log("error exists?", this.props.authError);
    this.props.signIn(this.state); //dispatches a login action
    this.handleHideLogin(); // hides the form after action is dispatched
};

我只想在操作被调度并且错误为空后隐藏表单。 (认证成功则自动返回null)

我尝试使用 setTimeout() 并且它在技术上有效,但我想知道是否有更“正确”的方法来做到这一点。

handleSubmit = e => {
    e.preventDefault();
    this.props.signIn(this.state);

     setTimeout(() => {
       if (this.props.authError) {
         console.log("returns error =>", this.props.authError);
       } else {
         console.log("no error =>", this.props.authError);
         this.handleHideLogin();
       }
     }, 500);
  };

我的部分组件供参考

<form onSubmit={!this.props.authError ? this.handleSubmit : null}> 
   //the above onSubmit is different if I use the setTimeout method.
          <div className="modal-login-body">
            <div className="modal-login-input">
              <input
                type="email/text"
                name="email"
                autoComplete="off"
                onChange={this.handleChange}
                required
              />
              <label htmlFor="email" className="label-name">
                <span className="content-name">EMAIL</span>
              </label>
            </div>
            <div className="modal-login-input">
              <input
                type="password"
                name="password"
                autoComplete="off"
                onChange={this.handleChange}
                required
              />
              <label htmlFor="password" className="label-name">
                <span className="content-name">PASSWORD</span>
              </label>
            </div>
          </div>
          <div className="my-modal-footer">
            <p className="login-failed-msg">
              {this.props.authError ? this.props.authError : null}
            </p>
            <button type="submit" className="complete-login-button">
              LOGIN
            </button>
            <a href="CHANGE" className="forgot-password">
              <u>Forgot your password?</u>
            </a>
          </div>
        </form>

【问题讨论】:

    标签: javascript reactjs firebase redux firebase-authentication


    【解决方案1】:

    我假设this.props.signIn 是一个异步函数。 因此this.props.authError 是异步更新的,这就是为什么如果你设置超时它在某些情况下会起作用(当你得到短于 5 秒的响应时)。

    解决它的一种方法是使用thencatch 而不更新表单的状态

    handleSubmit = e => {
        e.preventDefault();
        this.props.signIn(this.state).then(resp => {
            this.setState({userIsValid: true, failure: null})
            this.onUpdate(userIsValid);
        })
        .catch(err => {
           this.setState({userIsValid: false, failure: "Failed to login"})
        });
    }
    

    并使用if-else 来确定是显示表单还是显示您的网站

    class App extends React.Component {
      render() {
        if (this.state.isValidUser) {
          return <Main />
        } else {
          return <LoginForm onUpdate={(isValid) => {this.setState({isValidUser: isValid})} />
        }
      }
    }
    
    

    换句话说,LoginForm 组件存储用户名、密码、失败(登录失败的错误消息)和 isValidUser(确定登录是否成功)。 应用程序有一个状态来确定显示什么,网站或登录组件。使用 onUpdate 作为 props 传递给登录组件,我们可以更新 App 的状态并在登录成功时显示网站。

    希望对你有帮助。

    【讨论】:

    • 感谢您的帮助,我真的不想更改我的状态,因为我必须更改所有身份验证设置。我很感激你的付出。
    【解决方案2】:

    我通过对整个组件进行条件渲染解决了这个问题。 如果我登录了,我使用 Redirect from react-router-dom 来不渲染元素。

    如果我已登录,则无论如何都不需要显示登录表单。

       if (this.props.loggedOut) {
          <form onSubmit={this.handleSubmit}>
            //...
          </form>
        } else {
          return <Redirect to="/" />;
        }
    

    【讨论】:

      猜你喜欢
      • 2022-01-05
      • 2020-01-16
      • 2019-05-22
      • 2020-08-01
      • 1970-01-01
      • 2011-11-01
      • 2017-04-14
      • 2022-01-18
      • 1970-01-01
      相关资源
      最近更新 更多