我刚刚开始使用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组件中控制台这些值时,我也会得到相同的结果。我不知道为什么会这样。我使用自定义钩子错了吗?
答案 0 :(得分:1)
使用钩子更新状态是异步的,就像类组件中的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>