上下文提供程序上的值不会更改



所以,我正在学习 React Context,并尝试通过为我的 React Native 应用程序创建身份验证状态来实现它。我尝试遵循本·阿瓦德的回购。这是我到目前为止得到的:

// AuthContext.tsx
export const AuthContext = createContext<{
user: null | string;
login: () => void;
}>({
user: null,
login: () => {},
});
export const AuthProvider = ({ children }: Props) => {
const [user, setUser] = useState<null | string>(null);
const { user: contextUser } = useContext(AuthContext);
return (
<AuthContext.Provider
value={{
user,
login: () => {
setUser("My Name");
console.log("Auth Provider pressed");
console.log("user (state) " + user);
console.log("contextUser (context) " + contextUser);
},
}}
>
{children}
</AuthContext.Provider>
);
};
// Navigation.tsx
export const Navigation = ({}: Props) => {
const { user } = useContext(AuthContext);
return (
<AuthProvider>
{user ? <HomeScreen /> : <Button />}
</AuthProvider>
// Button.tsx
export const Button = ({}: Props) => {
const { login } = useContext(AuthContext);
return (
<View>
<Touchable
onPress={login}
>
<Text style={styles.container}>Submit</Text>
</Touchable>
</View>
)

身份验证提供程序有 2 个值。useruseState()获得的。并且,login调用setUser来更改useState()上的user,从而应该更改第一个提供程序值的user

onPress on Button 将从 AuthProvider 调用login()。身份验证提供程序上的login()将触发setUser,将useState()值的user从 null 更改为"我的名字"。在这部分之前,它按预期工作。

但是,即使按钮成功更改了useState()上的user值。它不会更改上下文中的user(更改为contextUser以"调试"目的),无论我单击按钮多少次,contextUser将始终为空。

Tl;dr:按下按钮后,AuthProvider 上的用户值不会更改。但是,用户使用状态更改。

那么,发生了什么?我做错了什么?有人知道如何解决这个问题吗?在过去的几个小时里,我一直在解决这个问题,并在谷歌上搜索了更多关于这个问题的信息。我的代码与他们的代码相似(我将我的代码与其他也使用上下文和身份验证的代码进行了比较),但不知何故,这段代码不起作用。

无论如何,在导航上,它还应该在上下文上的用户值更改为非空后自动重新呈现(成为主屏幕)。我还没有测试它是否会起作用(好吧,用户值永远不会改变)。任何人都可以查看它,看看它是否也可以按预期运行?

问题是您在不是AuthProvider子组件 (Navigation) 中使用上下文const { user } = useContext(AuthContext);

目前,导航组件仅接收上下文的默认状态。如果将console.log添加到上下文默认状态的login方法,您将看到此方法已执行,而不是作为上下文值返回的上下文login方法。例如:

// AuthContext.tsx
export const AuthContext = createContext<{
user: null | string;
login: () => void;
}>({
user: null,
login: () => {
// this will run if there is no context provider when being called
console.log('i am not working as expected')
},
});

但是,Button 组件正在接收完整的上下文,因为它是提供程序的子级,并且正在更新状态。

如果将AuthProvider"上一级",使其成为Navigation组件的父级,则导航组件也将接收更新的上下文数据。

例如:

const Wrapper = () => (
<AuthProvider> 
<Navigation />
</AuthProvider>
)

相关内容

最新更新