我刚刚开始使用反应钩子,在使用自定义钩子时遇到了一些问题。这可能是缺乏理解,但这是我正在尝试的
我的自定义钩子:
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
有效 false
错误 发现一些错误
相反,我看到的是:
有效真
错误空
有效真
错误空
钩子似乎没有更新本地状态。这是为什么呢?即使我尝试在钩子组件中控制台这些值,我也得到了同样的东西。 我不知道这是为什么。我使用自定义钩子是不是错了?
使用钩子更新状态是异步的,就像类组件中的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>
validate(( 函数时设置有效状态由于自定义钩子将有效状态值返回给您使用它的组件,因此您可以直接使用有效状态。
问题是,当你调用validate((并且"valid"的状态发生了变化,但是我们的组件需要告诉valid何时获得赋值渲染我们的组件。因此,在 react 函数组合中,我们可以简单地将 "valid" 作为 useImpact 的依赖项。然后,只要有效获取状态,它就会为我们的组件调用重新渲染。