组件本地状态未使用 React 自定义挂钩更新
Component local state not updating with react custom hooks
我刚开始使用 React Hooks,在使用自定义 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>
)
}
我希望在这里得到安慰的是:
valid true
error null
valid false
error Some error found
相反,我看到的是:
valid true
error null
valid true
error null
钩子似乎没有更新本地状态。为什么是这样?即使当我尝试在 hook 组件中控制这些值时,我也会得到同样的结果。我不明白这是为什么。我使用自定义钩子错了吗?
使用钩子更新状态是异步的,就像 class 组件中的 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>
我刚开始使用 React Hooks,在使用自定义 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>
)
}
我希望在这里得到安慰的是:
valid true
error null
valid false
error Some error found
相反,我看到的是:
valid true
error null
valid true
error null
钩子似乎没有更新本地状态。为什么是这样?即使当我尝试在 hook 组件中控制这些值时,我也会得到同样的结果。我不明白这是为什么。我使用自定义钩子错了吗?
使用钩子更新状态是异步的,就像 class 组件中的 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>