React Hooks: Как правильно настроить useEffect для обработки изменений состояния поля в форме? - PullRequest
0 голосов
/ 03 апреля 2020

Я пытаюсь создать универсальный c компонент формы для регистрации в случае входа в систему, регистрации и т.д. c. Я нахожусь в случае входа в систему, lol, и я заметил, что, несмотря на то, что состояние usernameError достигло значения false, т. Е. Пользователь продолжал вводить фактическое сообщение электронной почты, сообщение об ошибке будет сохраняться:

enter image description here

Я использую Ориентировочный для проверки, но проблема в моем компоненте, я думаю, потому что состояние ошибок изменяется в реальном времени, то есть проблема. Но я не уверен, как бы я подключил useEffect к моему onChange обработчику.

Вот мой компонент:

import React, { useState, useEffect } from 'react';

import {
  Loader,
  Dimmer,
  Transition,
  Button,
  Form,
  Grid,
  Header,
  Message,
  Segment
} from 'semantic-ui-react';

import axios from 'axios';

import {
  logInUser,
  userHasBeenVerified,
  userHasNotBeenVerified,
  resetCountNotVerified
} from '../../store/reducers/users/index';

import { Link } from 'react-router-dom';
import { validateInputs } from '../../utils/index';

import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';

function FormComponent({
  formType,
  match,
  isLoggedIn,
  accountVerified,
  userHasBeenVerified,
  resetCountNotVerified
}) {

  function isLoginForm() {
    console.log('formType; ', formType);

    return (
      <div className="login-form">
        {' '}
        {}
        <style>
          {`body > div, body > div > div, body > div > div > div.login-form { height: 100%;}`}{' '}
        </style>
        <Grid textAlign="center" style={{ height: '100%' }} verticalAlign="middle">
          <Grid.Column style={{ maxWidth: 450 }}>
            <Header as="h2" color="green" textAlign="center">
              Log-in to your account
            </Header>
            {console.log('usernameError ', usernameError)};
            <Form
              size="large"
              onSubmit={e => handleSubmit(e, formType)}
              error={formError}
            >
              <Segment stacked>
                <Form.Input
                  fluid
                  icon="user"
                  iconPosition="left"
                  placeholder="E-mail address, e.g. joe@schmoe.com"
                  name="username"
                  value={username}
                  onChange={e => handleChange(e)}
                  error={usernameError}
                />
                <Transition visible={usernameError} animation="scale" duration={duration}>
                  <Message error content={usernameFeedback} />
                </Transition>
                <Form.Input
                  fluid
                  icon="lock"
                  iconPosition="left"
                  placeholder="Password"
                  name="password"
                  type="password"
                  value={password}
                  onChange={e => handleChange(e)}
                  error={passwordError}
                />
                <Transition visible={passwordError} animation="scale" duration={duration}>
                  <Message error content={passwordFeedback} />
                </Transition>
                <Button color="green" fluid size="large" disabled={disableButton}>
                  Log-in
                </Button>
                <br />
                <Link to="/forgot_password">Forgot password?</Link>

                <Transition
                  visible={accountVerified === false ? true : false}
                  unmountOnHide={true}
                  animation="scale"
                  duration={duration}
                >
                  {isLoading ? (
                    <Dimmer active inverted>
                      <Loader />
                    </Dimmer>
                  ) : (
                    <Message
                      color="yellow"
                      centered="true"
                      header={responseMessage[0]}
                      content={responseMessage[1]}
                    />
                  )}
                </Transition>

                <Transition
                  visible={formError}
                  unmountOnHide={true}
                  animation="scale"
                  duration={duration}
                >
                  {isLoading ? (
                    <Dimmer active inverted>
                      <Loader />
                    </Dimmer>
                  ) : (
                    <Message
                      error
                      centered="true"
                      header={responseMessage[0]}
                      content={responseMessage[1]}
                    />
                  )}
                </Transition>

                <Transition
                  visible={formSuccess}
                  unmountOnHide={true}
                  animation="scale"
                  duration={duration}
                >
                  {isLoading ? (
                    <Dimmer active inverted>
                      <Loader />
                    </Dimmer>
                  ) : (
                    <Message
                      success
                      header={responseMessage[0]}
                      content={responseMessage[1]}
                    />
                  )}
                </Transition>
              </Segment>
            </Form>
            {formError ? (
              <Transition visible={formError} animation="scale" duration={1000}>
                {isLoading ? (
                  <Dimmer active inverted>
                    <Loader />
                  </Dimmer>
                ) : (
                  <Message>
                    <Link to="/register">Register</Link>{' '}
                  </Message>
                )}
              </Transition>
            ) : null}
          </Grid.Column>{' '}
        </Grid>{' '}
      </div>
    );
  }


  function loginSubmit() {
    axios
      .post('http://localhost:8016/users/login', {
        username: username,
        password: password
      })
      .then(response => {
        console.log('response', response);
        if (response.status === 200) {
          userHasBeenVerified();
          setTimeout(() => {
            logInUser();
            history.push('/profile');
          }, 5000);
          setUsername('');
          setPassword('');
          setFormError(false);
          setFormSuccess(true);
          setIsLoading(false);
          setResponseMessage(response.data.msg);
        }
      })
      .catch(function(error) {
        if (error.response) {
          if (error.response.status === 401) {
            userHasNotBeenVerified();
            setUsername('');
            setPassword('');
            setFormError(false);
            setFormSuccess(true);
            setIsLoading(false);
            setResponseMessage(error.response.data.msg);
          }
          if (error.response.status === 404) {
            resetCountNotVerified();
            setUsername('');
            setPassword('');
            setFormError(true);
            setFormSuccess(false);
            setIsLoading(false);
            setResponseMessage(error.response.data.msg);
          }
          console.log('error.response.data', error.response.data);
          console.log('error.response.headers', error.response.headers);
        }
      });
  }


  var Forms = {
    Login: [isLoginForm, loginSubmit],
  }

  var [fadeUp, setFadeUp] = useState('fade up');
  var [duration, setDuration] = useState(500);
  var [name, setName] = useState('');
  var [username, setUsername] = useState('');
  var [usernameFeedback, setUsernameFeedback] = useState('');
  var [usernameError, setUsernameError] = useState(false);
  var [userNameDup, setUserNameDup] = useState(false);
  var [password, setPassword] = useState('');
  var [passwordFeedback, setPasswordFeedback] = useState('');
  var [passwordError, setPasswordError] = useState(false);
  var [password_confirmation, setPasswordConfirmation] = useState('');
  var [passwordConfirmationError, setPasswordConfirmationError] = useState(false);
  var [passwordConfirmationFeedback, setPasswordConfirmationFeedback] = useState('');
  var [formSuccess, setFormSuccess] = useState(false);
  var [formError, setFormError] = useState(false);
  var [disableButton, setDisableButton] = useState(true);
  var [isLoading, setIsLoading] = useState(false);
  var [responseMessage, setResponseMessage] = useState({});
  var [tokenExpired, setTokenExpired] = useState(false);
  var [responseCodeSuccess, setResponseCodeSuccess] = useState(false);
  var [error, setError] = useState(false);

  useEffect(() => { /* Not sure what to do here */
     setUsernameError();
     setPassword();
  // }, []);

  function handleChange(e) {
    console.log('e ', e);
    e.persist();
    if (e.target.name === 'username') {
      console.log('username', e.target.name);
      setUsername(e.target.value);
    }

    if (e.target.name === 'password') {
      console.log('password', e.target.name);
      setPassword(e.target.value);
    }

    validateInputs(
      formType,
      username,
      setUsernameError,
      setUsernameFeedback,
      password,
      setPasswordError,
      setPasswordFeedback,
      setDisableButton
    );
  }

  function handleSubmit(event, formType) {
    event.preventDefault();

    return Forms[formType][1]();
  }
  console.log('formType; ', formType);
  return Forms[formType][0]();
}

function mapStateToProps(state) {
  const { users } = state;
  const { accountVerified, isLoggedIn } = users;

  return { accountVerified, isLoggedIn };
}

const mapDispatchToProps = dispatch =>
  bindActionCreators(
    { logInUser, userHasBeenVerified, userHasNotBeenVerified, resetCountNotVerified },
    dispatch
  );

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(FormComponent);

Итак, чтобы подвести итог, как у меня useEffect прислушайтесь к изменениям состояний ошибок для userNameError и passwordError, поскольку я считаю, что это проблема.

Обновление:

Это демонстрационная версия о том, что я думал, что имел в виду Ярз ..

 useEffect(() => {
    if (usernameError) {
      return usernameError;
    }

    if (passwordError) {
      return passwordError;
    }
  }, [usernameError, passwordError]);

Ответы [ 2 ]

1 голос
/ 03 апреля 2020

Хотя вы можете отслеживать изменения во входных данных с помощью массива зависимостей в useEffect, может быть неприятно иметь ошибочный пользовательский интерфейс (красные фоны), даже если входные данные нетронуты или введено допустимое значение.

Почему бы и нет проверить форму onSubmit и избежать useEffect здесь? Мне кажется, это лучший способ проверки формы с помощью Semanti c UI React.

1 голос
/ 03 апреля 2020

Второй аргумент для useEffect - это массив вещей для наблюдения, чтобы он знал, когда стрелять. С вашим текущим пустым массивом, он срабатывает только при монтировании (и если вы включите возврат, это сработает при unMount). Когда вы хотите его уволить? Попробуйте изменить это на [passwordError, userNameError].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...