reactjs - 上下文值的提供者不会改变
问题描述
我正在尝试在一个新的 react+typescript 示例项目中学习 ContextAPI。
我想管理语言环境/身份验证。
我必须初始化我的上下文值(Typescript / eslint 需要),特别是登录/注销功能,或者“App.tsx”中发生错误:“无法调用可能未定义的对象”。
是的,我尝试如下初始化我的上下文:
const AuthContext = React.createContext<ContextProps>({
...initialState,
login: () => {
throw new Error("login() not implemented yet");
},
logout: () => {
throw new Error("logout() not implemented yet");
}
});
现在的问题是,当我定义登录/注销功能并作为值传递给我的提供者时,我的按钮会抛出“尚未实现登录”错误。
这是我的代码:
// ./App.tsx
import React from "react";
import { NavItem, Button } from "reactstrap";
import * as Context from "./contexts";
const App = () => {
return (
<Context.Language.Consumer>
{({ locale, translation, switchLocale }) => (
<Context.Auth.Consumer>
{Auth => (
<NavItem right>
{Auth.isLoggedIn ? (
<Button onClick={() => Auth.logout()}>
{translation.logout}
</Button>
) : (
<Button onClick={() => Auth.login()}>
{translation.login}
</Button>
)}
</NavItem>
)}
</Context.Auth.Consumer>
)}
</Context.Language.Consumer>
);
};
export default App;
--
// ./contexts/AuthContext.tsx
import React, {Component} from "react";
type ContextProps = {
isLoggedIn: boolean;
login: () => void;
logout: () => void;
};
const initialState = { isLoggedIn: false };
type Props = {};
type State = {} & typeof initialState;
const AuthContext = React.createContext<ContextProps>({
...initialState,
login: () => {
throw new Error("login() not implemented yet");
},
logout: () => {
throw new Error("logout() not implemented yet");
}
});
class AuthProvider extends Component<Props, State> {
readonly state = initialState;
login = () => {
this.setState({
isLoggedIn: true
});
};
logout = () => {
this.setState({
isLoggedIn: false
});
};
render() {
return (
<AuthContext.Provider
value={{...this.state, login: this.login, logout: this.logout}}
>
{this.props.children}
</AuthContext.Provider>
);
}
}
export const Consumer = AuthContext.Consumer;
export const Provider = AuthProvider;
最后:
// ./contexts/index.js
import * as Auth from "./AuthContext";
import * as Language from "./LanguageContext";
export { Auth, Language };
似乎新的登录/注销定义没有传递给 AuthContext 中的提供者。我很确定我错过了 ContextAPI 中的一个概念,并且我没有正确理解其背后的逻辑。感谢您的建议。
解决方案
您需要使用新上下文添加提供程序。React 将向上查找第一个上下文提供者,如果没有,则消费者获取默认值。
const App = () => {
return (
<Context.Language.Consumer>
{({ locale, translation, switchLocale }) => (
<Context.Auth.Provider>
<Context.Auth.Consumer>
{Auth => (
<NavItem right>
{Auth.isLoggedIn ? (
<Button onClick={() => Auth.logout()}>
{translation.logout}
</Button>
) : (
<Button onClick={() => Auth.login()}>
{translation.login}
</Button>
)}
</NavItem>
)}
</Context.Auth.Consumer>
<Context.Auth.Provider>
)}
</Context.Language.Consumer>
); };
推荐阅读
- javascript - 渲染新的 html 后,Javascript 库无法正确加载
- javascript - 使用 jest-next-dynamic 测试动态导入
- django - gcloud 构建 Django 网站的提交导致错误“没有 storage.objects.get 访问”
- c# - 在 C# 中制作一个 SAPI DLL,我有一个启动语音的函数,但我需要一个函数来检查状态。我怎么做?
- r - 为什么下面代码1中的结果?四舍五入到底什么时候发生?
- bash - 如何将带有负数作为名称的图像转换为动画/视频?
- python - 在 PyCharm 中创建新项目后出现“无效 Python SDK”错误
- c++ - 在 SFML 上检测到多个按键,无法以任何其他方式解决,并且在不同机器上的工作方式不同
- javascript - 如何将 Leaflet.Snap 添加到 Angular(11) 项目
- python - ProgrammingError:关系不存在