У меня проблемы с изменением значения на входе - PullRequest
0 голосов
/ 10 ноября 2019

Часть проекта выглядит следующим образом:

...
const INITIAL_STATE = {
  email: '',
  password: '',
  error: null
}

const SignInPage = () => {
  return(
    <div>
      <h2>Sign In</h2>
      <SignInForm/>
      <SignUpLink/>
    </div>
  )
}

const SignInFormBase = props => {
  const[init,setInit] = useState(INITIAL_STATE);
  const onSubmit = () => {

  }
  const onChange = (event) => {
    setInit({
      [event.target.name]: event.target.value
    })    
  }
  const isInvalid = init.password === '' || init.email === '';
  return(
    <form onSubmit={onSubmit}>
      <input
        name='email'
        value={init.email}
        onChange={onChange}
        type='text'
        placeholder='Email Address'
      />
      <input
        ...
      />
      <button disabled={isInvalid} type='submit'>Sign In</button>
      {init.error && <p>{init.error.message}</p>}
    </form>
  )
}

const SignInForm = compose(
  withRouter,
  withFirebase
)(SignInFormBase)
export default SignInPage;
export {SignInForm}

Проблема заключается в следующем: когда я заменяю значения в init на setInit в функции onChange, я получаю следующую ошибку.

Предупреждение. Компонент меняет контролируемый ввод текста типа на неуправляемый. Входные элементы не должны переключаться с контролируемого на неуправляемый (или наоборот). Выберите между использованием управляемого или неконтролируемого элемента ввода в течение срока службы компонента.

Примечание: У меня такая же проблема в разделе паролей

1 Ответ

1 голос
/ 10 ноября 2019

Вы удаляете часть кода, но я предполагаю, что вы недостаточно хорошо прочитали документацию о перехватывании ответов. Используя хуки, вы не получите замену для setState, который ранее объединял значения. Поэтому, когда вы вызываете

setInit({
   [event.target.name]: event.target.value
})

, вы заменяете всю переменную init новым объектом, поэтому другое поле будет указывать на неопределенное значение, а реакция будет изменять компонент на неуправляемый, а затем снова на контролируемый при вводе значения. ,Если вы хотите сохранить объект в состоянии, вы должны выполнить слияние самостоятельно. Проще всего было бы использовать объектный разброс как

  setInit({
    ...init, // <- spread old state
    [event.target.name]: event.target.value
  })

С этим кодом старое состояние останется между входами. Я также предложил бы вам не выводить свойство состояния из имени поля, так как позже вы можете легко представить ошибку, которую вы можете создать при глобальном каррировании onChange, как

const onChange = (field) => (event) => {
  setInit({
   ...init,
   [field]: event.target.value
  })
}

return (
  <input onChange={onChange('name')} />
)
...