我有一组屏幕(目前为3个),只有当用户在前一个屏幕上执行某些操作时才能访问,如单击一些复选框和几个链接.我正在使用REACTION-CONTEXT将该信息传递给这些屏幕.
代码的精髓如下
Consent.tsx个
const onConsentButtonClick = () => {
setMyContext({userConsent: true});
navigate("postConsent"); // I am using react-router v6. navigate = useNavigate();
}
PostConsent.tsx个
useEffect(() => {
if(!myContext.userConsent) { // userConsent is always undefined on render
// show errors and fallback to Consent.tsx
}
}, []);
这不起作用,因为它看起来像是在上下文更新之前呈现了PostConsend组件.我使用超时验证了这一点.如果我按如下所示更改按钮点击功能,它将正常工作.
const onConsentButtonClick = () => {
setMyContext({userConsent: true});
setTimeout(() => {
navigate("postConsent");
}, 1000);
}
有没有办法确保在导航到下一个屏幕之前上下文更新已经完成?
我使用的语境是正确的吗?有没有更好的方法来实现这一点?
在我的情况下,props 钻取不是一个选项,也不是通过位置传递状态(因为我不希望浏览器在这些屏幕集上工作).
请务必建议是否有更好的替代方法来实现这一点.
编辑: 以下是我的完整上下文文件
const MyContext = createContext(null);
export function MyProvider({ children }) {
const [myContext, setMyContext] = useState({});
return (
<MyContext.Provider value={{myContext, setMyContext}}>
{children}
</MyContext.Provider>
);
}
export const useMyContext = () => {
return useContext(MyContext);
}
我在我的组件中使用这个钩子
const {myContext, setMyContext} = useMyContext();
UPDATE:个 基于下面的回答,我编写了一个定制钩子来封装上下文设置部分和实际设置上下文后的导航
type SetContextAndNavigate = {
context: any,
navigate: string
}
const defaultHookValues: SetContextAndNavigate = { context: {initialHookValue: "hook"}, navigate: "nowhere" };
function useSetContextAndNavigate() {
const { myContext, setMyContext } = useMyContext();
const [currentValues, setAndNavigate] = useState(defaultHookValues);
const navigate = useNavigate();
const setValuesBeforeNavigation = (args: SetContextAndNavigate) => {
setAndNavigate(args);
setMyContext(args.context);
}
useEffect(() => {
if(currentValues.context == myContext) {
navigate(currentValues.navigate);
}
}, [myContext]);
return setValuesBeforeNavigation;
}
组件中的用法:
const setContextAndNavigate = useSetContextAndNavigate();
setContextAndNavigate({context: {...consents}, navigate: "postConsent"});