新的反应...登录时状态未更新

时间:2020-10-04 13:46:13

标签: reactjs

寻找正确方向的轻推。处理React项目并使用钩子。是的,已经阅读了文档,但是还没有完全理解。

询问与登录例程有关。登录表单有效,但是直到重复提交后,它才反映失败的登录状态;所以我得到的是以前的状态,而不是当前的状态。

尝试useEffect ...不变。代码紧随其后,并感谢任何建设性的反馈意见:

从“登录”表单

let devicesInfo = [
  { '96abc32b47fc10c88704b9a799c65b5c05455f4a9ef92013': '::1' },
  { '96abc32b47fc10c88704b9a799c65b5c05455f4a9ef92013': '::1' },
  { '96abc32b47fc10c88704b9a799c65b5c05455f4a9ef92013': '::1' }
  ]

let deviceId= "96abc32b47fc10c88704b9a799c65b5c05455f4a9ef92013"

从身份验证切片中:

import React, { useState, useEffect, useRef } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { Redirect } from 'react-router-dom'

import getAuthStatus from 'common/cyclone/auth/authenticated.status'

import {
  authenticateByLogin,
  authenticationSelector,
} from '../services/auth.service'

import Form from 'react-validation/build/form'
import Input from 'react-validation/build/input'
import CheckButton from 'react-validation/build/button'

const required = (value) => {
  if (!value) {
    return (
      <div className="alert alert-danger" role="alert">
        This field is required!
      </div>
    )
  }
}

const Login = (props) => {
  const form = useRef()
  const checkBtn = useRef()

  const [username, setUsername] = useState('')
  const [password, setPassword] = useState('')
  const [loading, setLoading] = useState(false)
  const [errorMessage, setErrorMessage] = useState(null)

  const dispatch = useDispatch()

  const { session, hasErrors } = useSelector(authenticationSelector)

  useEffect(() => {}, [session, hasErrors])

  const onChangeUsername = (e) => {
    const username = e.target.value
    setUsername(username)
  }

  const onChangePassword = (e) => {
    const password = e.target.value
    setPassword(password)
  }

  const handleLogin = (e) => {
    e.preventDefault()
    setLoading(true)
    form.current.validateAll()
    if (checkBtn.current.context._errors.length === 0) {
      dispatch(authenticateByLogin(username, password))
        .then(() => {
          setLoading(false)
          if (hasErrors) {
            setErrorMessage(session.error.message)
          } else {
            //props.history.push('/profile')
            // window.location.reload()
          }
        })
        .catch(() => {
          setLoading(false)
        })
    } else {
      setLoading(false)
    }
  }

  if (session.success) {
    //console.log(session.success)
    return <Redirect to="/profile" />
  }

  if (getAuthStatus()) {
    return <Redirect to="/profile" />
  }

  return (
    <div className="col-md-12">
      <div className="card card-container">
        <img
          src="//ssl.gstatic.com/accounts/ui/avatar_2x.png"
          alt="profile-img"
          className="profile-img-card"
        />

        <Form onSubmit={handleLogin} ref={form}>
          <div className="form-group">
            <label htmlFor="username">Username</label>
            <Input
              type="text"
              className="form-control"
              name="username"
              value={username}
              onChange={onChangeUsername}
              validations={[required]}
            />
          </div>

          <div className="form-group">
            <label htmlFor="password">Password</label>
            <Input
              type="password"
              className="form-control"
              name="password"
              value={password}
              onChange={onChangePassword}
              validations={[required]}
            />
          </div>

          <div className="form-group">
            <button className="btn btn-primary btn-block" disabled={loading}>
              {loading && (
                <span className="spinner-border spinner-border-sm"></span>
              )}
              <span>Login</span>
            </button>
          </div>

          {hasErrors && (
            <div className="form-group">
              <div className="alert alert-danger" role="alert">
                {errorMessage}
              </div>
            </div>
          )}
          <CheckButton style={{ display: 'none' }} ref={checkBtn} />
        </Form>
      </div>
    </div>
  )
}

export default Login

2 个答案:

答案 0 :(得分:1)

尝试更改hasError更改时的消息

useEffect(()=> {
  if(hasErrors) {
   setErrorMessage(session.error.message)
  }
}, [hasErrors]);

答案 1 :(得分:0)

这是一些代码,因此我只是跳过以解决问题,而不是将所有内容分开。我最好的猜测是这部分:

dispatch(authenticateByLogin(username, password))
        .then(() => {
          setLoading(false)
          if (hasErrors) {
            setErrorMessage(session.error.message)
          } else {
            //props.history.push('/profile')
            // window.location.reload()
          }
        })
        .catch(() => {
          setLoading(false)
        })

在这里执行异步身份验证,然后根据“ hasError”执行操作。此“ hasError”来自一个钩子。我们(或至少我)不知道如何进行管理。问题是,您无法100%确保在then代码块中检查hasError确实值得信赖。该挂钩可能会在下一个渲染之后运行,这说明了为什么看到了上一个状态,而不是实际的状态。

最好的猜测是使用异步调用的响应,因为应该有一个=> authenticate.then((response)=> if(response.hasError)...) 通过此检查,您可以设置自己的错误状态,并且组件应该是最新的

让我知道这是否可以解决您的错误。