我正在尝试在一个新的react + typescript示例项目中学习ContextAPI。
我要管理区域设置/身份验证。
我必须初始化上下文值(Typescript / eslint要求),特别是登录/注销功能,或者在“ App.tsx”中发生错误:“无法调用可能是未定义的对象”。
对,我尝试初始化我的上下文,如下所示:
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(10)),
child: Container(
width: 400,
margin: EdgeInsets.only(top: 20),
padding: EdgeInsets.only(left: 10),
decoration: BoxDecoration(
border: Border(
left: BorderSide(
color: Color.fromRGBO(255, 167, 38, 1),
width: 5),
right: BorderSide(
width: .5,
color: Color.fromRGBO(116, 102, 102, .5)),
top: BorderSide(
width: .5,
color: Color.fromRGBO(116, 102, 102, .5)),
bottom: BorderSide(
width: .5,
color: Color.fromRGBO(116, 102, 102, .5)),
),
),
)
现在的问题是,当我定义登录/注销功能并将其作为值传递给提供程序时,我的按钮将引发“尚未实现登录”错误。
这是我的代码:
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;
似乎新的登录/注销定义未在AuthContext中传递给提供程序。我可以肯定的是,我错过了ContextAPI的概念,而且我不明白背后的逻辑。感谢您的建议。
答案 0 :(得分:0)
您需要添加具有新上下文的提供程序。 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>
); };