React Native (Expo) -能够从任何(嵌套的)子组件更新顶级组件的状态



我正在开发一个Expo应用程序,该应用程序使用使用SecureStore存储的jwt进行身份验证。顶层组件最初显示Login屏幕,但也检查SecureStore中是否存在JWT。如果JWT存在,则应用程序验证它是否仍然有效,如果存在,则应用程序将用户带到Landing页面,用户可以从该页面导航到许多其他页面,这些页面获取并显示各种数据。

我正在寻找一种方法来处理过期的JWT,这样,如果用户导航到一个页面,试图获取一些数据和API响应返回,例如401应用程序应该带用户回到登录屏幕。

top组件使用此状态来决定显示哪个页面

const [appState, setAppState] = useState(appStates.STARTUP_SETUP);

appState的有效值为:

const appStates = {
STARTUP_SETUP: "StartupSetup", // Initial state, during which the app checks for an existing valid JWT
SHOW_LOGIN_SCREEN: "ShowLoginScreen", // There is no stored JWT, app shows login screen
SHOW_SIGNUP_SCREEN: "ShowSignupScreen", // There is no stored JWT, app shows signup screen
SHOW_SIGNUP_CONFIRMATION_SCREEN: "ShowSignupConfirmationScreen", // There is no stored JWT, user just registered and is prompted to check their email for verification
USER_LOGGED_IN: "UserLoggedIn", // user logged in, JWT is stored
}

组件使用appState的方式如下:

if (appState === appStates.USER_LOGGED_IN) {
comp = <Landing onLogout={logUserOut} />;
} else if (appState === appStates.SHOW_LOGIN_SCREEN) {
comp = <Login onSuccessfulLogin={updateUser} onSignup={() => setAppState(appStates.SHOW_SIGNUP_SCREEN)} />;
} else if (appState === appStates.SHOW_SIGNUP_SCREEN) {
comp = <Signup onSuccessfulSignup={() => setAppState(appStates.SHOW_SIGNUP_CONFIRMATION_SCREEN)} onLogin={() => setAppState(appStates.SHOW_LOGIN_SCREEN)} />;
} else if (appState === appStates.SHOW_SIGNUP_CONFIRMATION_SCREEN) {
comp = <SignupConfirmation onLogin={() => setAppState(appStates.SHOW_LOGIN_SCREEN)} />
}

Landing有自己的子组件树。

我基本上是在寻找一种方法来做

setAppState(appStates.SHOW_LOGIN_SCREEN)

从我的应用程序的任何地方。

一种可能性是将钩子从顶部组件传递给Landing和每个子组件,但我觉得应该有一个更简单的方法。

编辑-解决方案

在顶部组件中,我创建了一个方法来删除令牌并将appState设置为SHOW_LOGIN_SCREEN

const deleteStoredToken = () => {
deleteToken();
setAppState(appStates.SHOW_LOGIN_SCREEN);
}
const appStateValue = { deleteStoredToken };

然后我创建了一个上下文(默认值)

export const AppContext = React.createContext({
deleteStoredToken: () => { }
});

我使用这个上下文通过提供appStateValue作为其值来包装top组件的子组件

return (
...
<AppContext.Provider value={appStateValue}>
{children}
</AppContext.Provider>
...
)

现在我可以在任何子组件中输入

const { deleteStoredToken } = useContext(AppContext);

和使用deleteStoredToken()

听起来您正在寻找状态管理解决方案。React Context是一个低成本的解决方案——请务必阅读文档中的注意事项。

有几十甚至几百个库提供了不同的方法来实现这一点。最受欢迎的可能是Redux和Mobx;它们提供了在组件之间共享复杂状态的专用方法。但是,如果它只针对一个值,并且不会经常更新,则使用上下文非常合适。

最新更新