【发布时间】:2020-02-22 01:28:53
【问题描述】:
我正在尝试使用私有路由和上下文向 React+Typescript 应用程序添加简单的身份验证。我有一个简单的登录组件,它带有一个按钮,它只是将上下文中的布尔变量authenticated 设置为true。私有路由应该检查这个 var 并重定向到登录组件,如果它不是真的,否则显示指定的组件。问题是authenticated 似乎总是错误的,我总是被重定向到登录页面。
当我调试它时,我可以看到 AuthContextProvider 中的setAuthenticated 函数在单击登录按钮时被调用。但是,如果我随后单击任何指向私有路由的链接,authenticated 总是错误的。
这是我的 App.tsx:
function App() {
return (
<AuthContextProvider>
<Router>
<Link to="/">Home</Link>
<Link to="/projects">Projects</Link>
<div>
<Route path="/login" component={Login} />
<PrivateRoute path="/" exact component={Home} />
<PrivateRoute path="/projects" component={Projects} />
</div>
</Router>
</AuthContextProvider>
);
}
export default App;
PrivateRoute.tsx:
interface PrivateRouteProps extends RouteProps {
// tslint:disable-next-line:no-any
component: any;
}
const PrivateRoute = (props: PrivateRouteProps) => {
const { component: Component, ...rest } = props;
return (
<AuthContextConsumer>
{authContext => authContext && (
<Route {...rest}
render={ props =>
authContext.authenticated === true ? (
<Component {...props} />
) : (
<Redirect to="/login" />
)
}
/>
)}
</AuthContextConsumer>
);
};
export default PrivateRoute;
AuthContext.tsx:
export interface AuthContextInterface {
authenticated: boolean,
setAuthenticated(newAuthState: boolean):void
}
const ctxt = React.createContext<AuthContextInterface>({
authenticated: false,
setAuthenticated: () => {}
});
export class AuthContextProvider extends React.Component {
setAuthenticated = (newAuthState:boolean) => {
this.setState({ authenticated: newAuthState });
};
state = {
authenticated: false,
setAuthenticated: this.setAuthenticated,
};
render() {
return (
<ctxt.Provider value={this.state}>
{this.props.children}
</ctxt.Provider>
);
}
}
export const AuthContextConsumer = ctxt.Consumer;
登录.tsx:
function Login() {
return (
<AuthContextConsumer>
{({ authenticated, setAuthenticated }) => (
<div>
<p>Login</p>
<form>
<input type="text" placeholder="Username"/>
<input type="password" placeholder="Password"/>
<button onClick={event => {
setAuthenticated(true);
}}>Login</button>
</form>
</div>
)}
</AuthContextConsumer>
);
}
export default Login;
我怀疑 AuthContextProvider 中的状态定义有问题。如果我在这里将authenticatedin 更改为 true,我会看到相反的行为,我永远不会看到登录页面。这应该是动态的吗?
【问题讨论】:
标签: reactjs typescript react-router react-context