繁体   English   中英

组件本地 state 未使用反应自定义挂钩进行更新

[英]Component local state not updating with react custom hooks

我刚开始使用反应钩子,在使用自定义钩子时遇到了一些问题。 可能缺乏理解,但这就是我正在尝试的

我的自定义钩子:

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

我期望在这里得到安慰的是:

有效 真实
错误 null
有效假
error 发现一些错误

相反,我看到的是:

有效 真实
错误 null
有效 真实
错误 null

看起来钩子没有更新本地 state。 为什么是这样? 即使我尝试在钩子组件中控制这些值,我也会得到同样的结果。 我不知道为什么会这样。 我使用自定义钩子错了吗?

Updating state with hooks is asynchronous just like setState in a class component is, and since the state is not mutated contentIsValid and contentError will still refer to the stale old state and not the new state.

如果您渲染 state 变量,您将看到您的代码按预期工作。

 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>

valid state is set when you called validate() function and since the custom hook return valid state value to the component you use it at, you can directly use valid state.

问题是,当您调用 validate() 并且“valid”改变了它的 state 时,但是我们的组件需要告诉 valid 何时获得一个值分配来渲染我们的组件。 所以在反应功能组件中,我们可以简单地将“有效”作为 useEffect 的依赖项。 然后每当 valid 获得 state 时,它将为我们的组件调用重新渲染。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM