组件本地状态未使用react自定义钩子更新

时间:2019-03-28 19:17:48

标签: javascript reactjs react-hooks

我刚刚开始使用react挂钩,并且在使用自定义挂钩时遇到了一些问题。可能缺乏了解,但这是我正在尝试的

我的自定义钩子:

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>
    )
}

我希望在这里得到安慰:

  

有效true
错误null
有效false
错误找到一些错误

相反,我看到的是:

  

有效为真
错误为空
有效为真
错误为空

似乎钩子没有更新本地状态。为什么是这样?即使当我尝试在hook组件中控制台这些值时,我也会得到相同的结果。我不知道为什么会这样。我使用自定义钩子错了吗?

1 个答案:

答案 0 :(得分:1)

使用钩子更新状态是异步的,就像类组件中的setState一样,并且由于该状态未突变,contentIsValidcontentError仍将引用旧状态,而不是旧状态新状态。

如果呈现状态变量,您将看到代码按预期工作。

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>