Я хочу создать приложение React с логином. Чтобы поддерживать состояние пользователя, я хочу использовать Контекстный API, представленный в React 16.3. При реализации логина-маршрутизации я следовал пример в документации React Router.
Приведенный ниже исходный код является (как я надеюсь) очень упрощенным минимальным примером моей проблемы. Когда я открываю localhost:3000/protected в браузере, URL-адрес правильно меняется на localhost:3000/login, но компонент не отображается. Метод render() вроде не вызывается.
Как я могу убедить React отрендерить мой компонент входа в систему?
Вот мой исходный код.
App.js
import React, {Component} from 'react';
import {
BrowserRouter as Router,
Route
} from 'react-router-dom'
import Login from "./Login";
import Protected from "./Protected";
import ProtectedRoute from "./ProtectedRoute";
import UserContext from "./UserContext";
export default class App extends Component {
render() {
return (
<Router>
<UserContext.Provider value = {false}>
<div>
<ProtectedRoute path='/protected' component = {Protected}/>
<Route path='/login' component = {Login}/>
</div>
</UserContext.Provider>
</Router>
);
}
}
Login.js
import React from 'react';
export default class Login extends React.Component {
render() {
return <p>Login</p>;
}
}
UserContext.js
import React from "react";
const UserContext = React.createContext();
export default UserContext;
ProtectedRoute.js
import React from 'react'
import {Redirect, Route} from "react-router-dom";
import UserContext from './UserContext';
const ProtectedRoute = ({component: Component, ...rest}) => (
<Route {...rest} render = {props =>
<UserContext.Consumer>
{loggedIn =>
loggedIn === true
? <Component {...props} />
: <Redirect to = {{
pathname: '/login',
state: {from: props.location}
}}/>
}
</UserContext.Consumer>
}
/>
);
export default ProtectedRoute;
Protected.js
import React from 'react';
export default class Protected extends React.Component {
render () {
return <h2>protected</h2>;
}
}





Похоже, это ошибка: https://github.com/ReactTraining/react-router/issues/6072, и, возможно, даже ошибка React: https://github.com/facebook/react/issues/12551.
На данный момент вы можете обойти это, отрисовав Router и ваш поставщик контекста в отдельных компонентах. Вот так, например:
const Routes = () => (
<UserContext.Provider value = {false}>
<div>
<ProtectedRoute path='/protected' component = {Protected}/>
<Route path='/login' component = {Login}/>
</div>
</UserContext.Provider>
);
export default class App extends Component {
render() {
return (
<Router>
<Routes/>
</Router>
);
}
}