React Router не отображает компонент

Я хочу создать приложение 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>;
    }
}
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
4
0
1 311
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Похоже, это ошибка: 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>
        );
    }
}

Другие вопросы по теме