在React JS中重置状态

时间:2018-03-21 12:33:51

标签: javascript reactjs redux react-redux jsx

我在将errorText重置为原始状态时遇到问题。每次提交表单时都会出现错误,即使它们来自之前的提交,也会将所有错误添加到最后。

第一次单击空白表单 //我希望每次都有这个结果。

“错误:电子邮件无效。密码无效。”

第二次点击空白表格

“错误:电子邮件无效。密码无效。电子邮件无效。密码无效。”

代码段

class LoginForm extends Component {
constructor(props) {
  super(props)
  this.state = {
    details: {
      email: '',
      password: '',
    },
    hasError: false,
    errorText: 'Errors: \n',
  }
}

render() {
  let { hasError, errorText } = this.state
  const { LogUserIn } = this.props

  const onTapLogin = e => {

     // broken?
    if (hasError) {
      this.setState({
        hasError: false,
        errorText: 'Errors: \n',
      })
    }

    if (!check.emailValid(e.email)){
      this.setState({ 
        hasError: true,
        errorText: errorText += "\n - Email address is invalid. "
      })
    }

    if (!check.passwordValid(e.password)){
      this.setState({ 
        hasError: true,
        errorText: errorText += "\n- Password is invalid. "
      })
    }

    if (!hasError){
      LogUserIn(e)
    } 
  }

  return (
    <div {...cssLoginFormContainer}>
      <div {...cssLoginFormHeader}>SIGN IN</div>

      <div {...(hasError ? cssErrorText : cssErrorText_hide)}>
        {errorText}
      </div>
      ...
      // the form.

3 个答案:

答案 0 :(得分:1)

我会在这里采用不同的方法来显示错误,即将错误消息作为您所在州的单独值实现:

this.state = {
   ...,
   errorEmail: '',
   errorPassword: ''
}

设置状态(针对您的特定错误):

this.setState({ 
    hasError: true,
    errorEmail: "\n - Email address is invalid. "
  })

您的errorText可以在单独的函数中提取,以返回错误文本:

function errorText() {
   return `Errors: ${this.state.errorEmail} ${this.state.errorPassword}`
}

注意:您还可以将错误嵌套在单个errors对象下,如下所示:

this.state = {
   ...,
   errors = { email: '', password: '' }
}

在这种情况下,请注意状态更新(因为它是嵌套的)。更多信息:How to update a nested state in React

答案 1 :(得分:1)

这里有两个问题:首先,你使用+ =来改变状态以连接字符串。你可能只想使用+。 只应使用setState更改状态。当您执行errorText = erroText+="whatever"时,您正在更改字符串。在控制台上尝试以下代码:

x = "hello"
y = x+=" world"
x
y

您会看到在尝试将y设置为新值时更改了x

如果你这样做

x = "hello"
y = x+ " world"
x
y

您只会看到y更改

其次,你在一个函数中多次使用setState,这会导致竞争条件

您应该尝试在结尾处仅设置一次状态,将字符串和布尔值保留在变量中并使用它们来设置状态

答案 2 :(得分:1)

  • 渲染功能不应包含任何副作用,因此最好在onTapLogin功能之外使用render功能。
  • 我多次看不到setState点,因为setState可能会触发React生命周期,而 NOT 会立即执行(It&#39; s一个async函数)。

我重新安排了您的代码以解决问题,但您获得的代码并未调用onTapLogin函数,因此您可能需要更改它以适合您的实际代码:

class LoginForm extends Component {
  constructor(props) {
    super(props);
    this.state = {
      details: {
        email: '',
        password: '',
      },
      hasError: false,
      errorText: null,
    };
  }

  onTapLogin = e => {
    let errorText = 'Errors: \n';
    let hasError = false;

    if (!check.emailValid(e.email)) {
      errorText += 'Email address is invalid.\n';
      hasError = true;
    }
    if (!check.passwordValid(e.password)) {
      errorText += 'Password is invalid.\n';
      hasError = true;
    }

    if (!hasError) {
      this.logUserIn(e);
    } else {
      this.setState({
        errorText,
        hasError,
      });
    }
  };

  logUserIn = e => {}

  render() {
    const { hasError, errorText } = this.state;
    const { LogUserIn } = this.props;

    return <div>{hasError && <p>{errorText}</p>}</div>;
  }
}