Локальное состояние компонента не обновляется с помощью реагирующих пользовательских хуков - PullRequest
1 голос
/ 28 марта 2019

Я только начинаю использовать реакционные хуки, и у меня возникают некоторые проблемы при использовании пользовательских хуков. Это, вероятно, отсутствие понимания, но вот что я пытаюсь

Мой пользовательский крючок:

import React, { useState } from "react"

export const useValidateContent = initState => {
    const[valid, setValid] = useState(initState)
    const[errorMsg, setErrorMsg] = useState(null)

    const validate = () => {
      // Update component state to test
      setValid(false)
      setErrorMsg('Some error found')
    }

    return [valid, validate, errorMsg]

}

Мой родительский контейнер, который использует пользовательский хук:

import React, { useState, useEffect } from 'react'
import { useValidateContent } from './hooks/useValidateContent'


export default function ParentComp () {

    const [contentIsValid, validate, contentError] = useValidateContent(true)

    const initValidate = () => {
        // values before running validate
        console.log('valid', contentIsValid)
        console.log('error', contentError)
        validate()
        // values after running validate
        console.log('valid', contentIsValid)
        console.log('error', contentError)
    }

    return (
      <div>
        <button onclick={initValidate} />
      </div>
    )
}

То, что я ожидал утешить здесь, было:

допустимо верно
ошибка обнуляется
правильно ложно
обнаружена ошибка

Вместо этого я вижу:

действительно верно
ошибка ноль
действительно верно
ошибка ноль

Кажется, что ловушка не обновляет локальное состояние. Почему это? Даже когда я пытаюсь утешить эти значения внутри компонента ловушки, я получаю то же самое. Я не могу понять, почему это так. Я неправильно использую кастомные хуки?

1 Ответ

1 голос
/ 28 марта 2019

Обновление состояния с помощью ловушек является асинхронным, как и setState в компоненте класса, и, поскольку состояние не является мутированным, contentIsValid и contentError будут по-прежнему ссылаться на устаревшее старое состояние, а не на новое состояние.

Если вы визуализируете свои переменные состояния, вы увидите, что ваш код работает должным образом.

const { useState } = React;

const useValidateContent = initState => {
  const [valid, setValid] = useState(initState);
  const [errorMsg, setErrorMsg] = useState("");

  const validate = () => {
    setValid(false);
    setErrorMsg("Some error found");
  };

  return [valid, validate, errorMsg];
};

function ParentComp() {
  const [contentIsValid, validate, contentError] = useValidateContent(true);

  const initValidate = () => {
    // values before running validate
    console.log("valid", contentIsValid);
    console.log("error", contentError);
    validate();
    // values after running validate
    console.log("valid", contentIsValid);
    console.log("error", contentError);
  };

  return (
    <div>
      <button onClick={initValidate}>initValidate</button>
      contentIsValid: {contentIsValid.toString()}, contentError: {contentError}
    </div>
  );
}

ReactDOM.render(<ParentComp />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>
...