Реагировать маршрутизатор с поставщиком контекста
У меня есть 3 страницы: логин, панель инструментов и логи. Я использую Context api для защиты панели инструментов и страницы логов. Если пользователь не вошел в систему, он всегда перенаправляет на страницу входа. На панель инструментов и журналы у меня есть 2 ссылки для каждого компонента. Но эти ссылки не перенаправляют на панель инструментов и журналы, они перенаправляют на вход в систему.
AuthContext.js
import React from 'react';
import request from 'request';
const AuthContext = React.createContext();
class AuthProvider extends React.Component {
state = { isAuth: false,
error: ''
}
onLogin = (login, password) => {
this.setState({ isAuth: true})
}
onLogout = () => {
this.setState({ isAuth: false })
}
render() {
return (
<AuthContext.Provider
value={{
isAuth: this.state.isAuth,
onLogin: this.onLogin,
onLogout: this.onLogout,
error: this.state.error
}}>
{this.props.children}
</AuthContext.Provider>
)
}
}
const AuthConsumer = AuthContext.Consumer
export { AuthProvider, AuthConsumer }
App.js
import React, { Component } from 'react';
import {Switch, BrowserRouter, Route} from 'react-router-dom';
import Dashboard from './views/Dashboard';
import Login from './views/Login' ;
import Logging from './views/Logging';
import ProtectedRoute from './ProtectedRoute'
import { AuthProvider } from './AuthContext';
import './App.css';
class App extends Component {
render() {
return(
<BrowserRouter>
<AuthProvider>
<Login />
<Switch>
<ProtectedRoute path="/" component={Dashboard} />
<ProtectedRoute path="/logs" component={Logging} />
<Route path="/login" component={Login} />
</Switch>
</AuthProvider>
</BrowserRouter>
);
}
}
ProtectedRoute.js
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import { AuthConsumer } from './AuthContext';
const ProtectedRoute = ({
component: Component, ...rest }) => (
<AuthConsumer>
{({ isAuth }) => (
<Route
render={
props =>
isAuth
? <Component {...props} />
: <Redirect to="/" />
}
{...rest}
/>
)}
</AuthConsumer>
)
export default ProtectedRoute;
Sidebar.js (который входит в Dashboard.js)
import React from 'react';
import {NavLink as Router} from 'react-router-dom';
import { Collapse, Navbar, NavbarToggler, NavbarBrand, Nav, NavItem, NavLink
} from 'reactstrap';
export default class Sidebar extends React.Component {
constructor(props) {
super(props);
this.toggleNavbar = this.toggleNavbar.bind(this);
this.state = {
collapsed: true
};
}
toggleNavbar() {
this.setState({
collapsed: !this.state.collapsed
});
}
render() {
return (
<div className="sidebar">
<Navbar color="faded" light>
<NavbarToggler onClick={this.toggleNavbar} className="mr-2" />
<NavbarBrand href="/" className="mr-auto"></NavbarBrand>
<Collapse isOpen={!this.state.collapsed} navbar>
<Nav navbar>
<NavItem>
<NavLink href="/">Home</NavLink> //here the link to index (dashboard component)
</NavItem>
<NavItem>
<NavLink tag={Router} to="/logs" activeClassName="active">Logs</NavLink> //Here the link to logs component
</NavItem>
</Nav>
</Collapse>
</Navbar>
</div>
);
}
}
Login.js
import React, {Component} from 'react';
import {Container, Row, Col, CardGroup, Card, CardBody, Button, Input,
InputGroup, InputGroupAddon, InputGroupText, Label} from 'reactstrap';
import { AuthConsumer } from '../AuthContext'
import { Redirect } from 'react-router-dom';
class Login extends Component {
state = { login: '',
password: ''
}
render() {
return(
<AuthConsumer>
{
({ isAuth, onLogin, error }) =>
isAuth ? (
<Redirect to="/dashboard" />
) : (
<div className="app flex-row align-items-center">
<Container>
<Row className="justify-content-center">
<Col md="8">
<CardGroup>
<Card className="p-4">
<CardBody>
<h1>Login</h1>
<p className="text-muted">Sign In to your account</p>
<InputGroup className="mb-3">
<InputGroupAddon addonType="prepend">
<InputGroupText>
<i className="icon-user"></i>
</InputGroupText>
</InputGroupAddon>
<Input name="login" ref={this.login} value={this.state.login} onChange={e => this.setState({login:e.target.value})} type="text"placeholder="Username"/>
</InputGroup>
<InputGroup className="mb-4">
<InputGroupAddon addonType="prepend">
<InputGroupText>
<i className="icon-lock"></i>
</InputGroupText>
</InputGroupAddon>
<Input onChange={e => this.setState({password: e.target.value })} type="password" placeholder="Password"/>
</InputGroup>
<Row>
<Col xs="6">
<Button color="primary" className="px-4" onClick={() => onLogin(this.state.login, this.state.password)}>Login</Button>
</Col>
<Col xs="6" className="text-right">
<Button color="link" className="px-0">Forgot password?</Button>
</Col>
</Row>
<Row>
<Col xs="6">
<p /> <Label for="errorOnLogin">{error}</Label>
</Col>
</Row>
</CardBody>
</Card>
</CardGroup>
</Col>
</Row>
</Container>
</div>
)}
</AuthConsumer>
);
}
}
export default Login;