У меня есть форма, которая отображает дочерний компонент при его отправке. Затем я хочу отправить дочернюю форму и запустить действие в родительском компоненте. Проблема заключается в том, что состояние не обновляется в родительском компоненте, когда я запускаю действие в дочернем компоненте.
Я пытался использовать как 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}
.
Как я могу сделать эту работу?