Хук useState () не обновляет значение при изменении - PullRequest
0 голосов
/ 26 февраля 2020

Небольшой контекст, я пытаюсь создать форму для получения регистрации пользователя.

Сначала я написал код следующим образом.

import { useState } from 'react';


const SignupComponent = () => {
const [formData, setFormData] = useState({
    name: '',
    email: '',
    password: '',
    error: '',
    loading: false,
    message: '',
    showForm: true
})

const { name, email, password, error, loading, showForm } = formData;

const onChange = e => {
    setFormData({ ...formData, error: false, [e.target.name]: e.target.value })
    console.log(name)

}
const handleSubmit = async e => {
    e.preventDefault();
    console.table({ name, email, password, error, loading, showForm })
}


const signupForm = () => {
    return (
        <form onSubmit={handleSubmit}>
            <div className="form-group">
                <input type="text" className="form-control" placeholder="Enter Your Name" values={name} onChange={e => onChange(e)} />
            </div>

            <div className="form-group">
                <input values={email} onChange={e => onChange(e)} type="email" className="form-control" placeholder="Enter Your Email" />
            </div>

            <div className="form-group">
                <input values={password} onChange={e => onChange(e)} type="password" className="form-control" placeholder="Enter Your Password" />
            </div>

            <div>
                <button className="btn btn-primary">Signup</button>
            </div>
        </form>
    );

};
return <React.Fragment>{signupForm()}</React.Fragment>};
export default SignupComponent;

Я заметил, что в этом фрагменте кода состояние в setFormData не обновляется, имя журнала консоли или любое другое значение возвращает пустую строку.

результат для вышеуказанного кода

Но после настройки кода как такового

import { useState } from 'react';


const SignupComponent = () => {
const [formData, setFormData] = useState({
    name: '',
    email: '',
    password: '',
    error: '',
    loading: false,
    message: '',
    showForm: true
})

const { name, email, password, error, loading, showForm } = formData;

const handleChange = value => (e) => {
    setFormData({ ...formData, error: false, [value]: e.target.value })
    console.log(name)

}
const handleSubmit = async e => {
    e.preventDefault();
    console.table({ name, email, password, error, loading, showForm })
}


const signupForm = () => {
    return (
        <form onSubmit={handleSubmit}>
            <div className="form-group">
                <input type="text" className="form-control" placeholder="Enter Your Name" values={name} onChange={handleChange('name')} />
            </div>

            <div className="form-group">
                <input values={email} onChange={handleChange('email')} type="email" className="form-control" placeholder="Enter Your Email" />
            </div>

            <div className="form-group">
                <input values={password} onChange={handleChange('password')} type="password" className="form-control" placeholder="Enter Your Password" />
            </div>

            <div>
                <button className="btn btn-primary">Signup</button>
            </div>
        </form>
    );

};
return <React.Fragment>{signupForm()}</React.Fragment> };
export default SignupComponent;

Делает код работающим, и результат получается желаемым. Как на этом изображении. 2-й способ

Почему это ведет себя так. Почему первый способ не работает.

Ответы [ 2 ]

2 голосов
/ 26 февраля 2020

Вы забыли атрибут name в своих входах и атрибут value без s

<input name="email" value={email} onChange={onChange} ... />

затем

const onChange = e => {
    // The event will get passed as an argument even if you don't bind it in onChange={onChange}.
    console.log(e.target.name, e.target.value)
    setFormData({ ...formData, error: false, [e.target.name]: e.target.value })
}

Событие будет передано в качестве аргумента.

Это работает для второй причины, вы передаете имя в качестве аргумента

0 голосов
/ 26 февраля 2020

см. Документы, https://reactjs.org/docs/thinking-in-react.html

Односторонний поток данных React (также называемый односторонним связыванием) сохраняет все модульное и быстрое.


Важная вещь для решения вашего вопроса.

  1. Состояние функционального компонента (F C) изменено, пользовательский интерфейс перерисован.
  2. Но ваш signupForm Функция рендеринга объявлена ​​в F C.
  3. Итак, она перераспределяется как новая при изменении состояния RegistrationComponent.

Сначала. измените signupForm функцию рендеринга на компонент F C.

Секунда, Передайте реквизиты компоненту. Трид, повторно их использовал.

import React from 'react'; // React is required to render JSX

const FormInput = ({
  type,
  placeholder,
  value,
  onChange,
}) => (
  <div className="form-group">
    <input type={type} className="form-control" placeholder={placeholder} value={value} onChange={onChange} />
  </div>
);

const SignupComponent = () => {
  const [formData, setFormData] = React.useState({
    name: '',
    email: '',
    password: '',
    error: false,
    loading: false,
    message: '',
    showForm: true,
  });

  const {
    name, email, password, error, loading, showForm,
  } = formData;

  const handleChange = (value) => (e) => {
    setFormData({
      ...formData,
      error: false,
      [value]: e.target.value,
    });
    console.log(name);
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    console.table({
      name, email, password, error, loading, showForm,
    });
  };

  return (
    <form onSubmit={handleSubmit}>
      <FormInput type="text" value={name} placeholder="Enter Your Name" onChange={handleChange('name')} />
      <div>
        <button type="submit" className="btn btn-primary">Signup</button>
      </div>
    </form>
  );
};

export default SignupComponent;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...