我有一个在提交子组件时呈现子组件的表单。然后,我想提交子表单并在父组件中触发操作。问题是,当我在子级中触发操作时,状态未在父级组件中更新。
我尝试同时使用useState
和useReducer
钩子。我读到React钩子并不总是同步执行的,所以我尝试使函数异步并等待钩子调用。由于状态更新已排队,因此我也尝试将父函数包装在setTimeout(0)
中。这些都不起作用。我的eslint-plugin-react-hooks
都设置了两个规则,并且没有收到错误/警告,因此我知道挂钩调用是不正确的。这是当前的代码,带有useReducer
和setTimeout
:
父母
const initialState = { termsAccepted: false, showTerms: false };
function reducer(state, action) {
switch (action.type) {
case "toggleShowTerms":
return { ...state, showTerms: !state.showTerms };
case "toggleTermsAccepted":
return { ...state, termsAccepted: !state.termsAccepted };
default:
throw new Error();
}
}
const [state, dispatch] = useReducer(reducer, initialState);
...
const openTerms = event => {
event.preventDefault();
dispatch({ type: "toggleShowTerms" });
};
const exitTerms = accepted => {
dispatch({ type: "toggleShowTerms" });
dispatch({ type: "toggleTermsAccepted" });
setTimeout(() => handleTermsAndSubmit(), 0);
};
const handleTermsAndSubmit = () => {
// state is currently: {showTerms: true, termsAccepted: false}
// I want the exact opposite
}
return (
...
Form onSubmit={openTerms}>
...
<child show={state.showTerms} exit={exitTerms} />
)
孩子
const [show, setShow] = useState(props.show);
const [checked, setChecked] = useState(false);
useEffect(() => {
setShow(props.show);
}, [props.show]);
const toggleChecked = () => {
setChecked(!checked);
};
return (
...
<Button onClick={() => { props.exit(checked);}}>Submit<Button/>
)
在handleTermsAndSubmit
内,当前状态为:{showTerms: true, termsAccepted: false}
,但我希望它是:
{showTerms: false, termsAccepted: true}
。
我该如何做?