Форма входа React не работает при разбиении на компоненты

Как новичок в Reacteur, я следил за этим руководство, чтобы создать простую форму входа в систему с помощью reactjs. Все работает нормально и работает как задумано. Весь учебник основан на скрипте signle.

Вот окончательный код (из учебника):

import React from 'react'
import {
  BrowserRouter as Router,
  Route,
  Link,
  Redirect,
  withRouter
} from 'react-router-dom'

const authenticator = {
  isAuthenticated: false,
  authenticate(cb) {
    this.isAuthenticated = true
    setTimeout(cb, 100)
  },
  signout(cb) {
    this.isAuthenticated = false
    setTimeout(cb, 100)
  }
}

const Public = () => <h3>Public</h3>
const Protected = () => <h3>Protected</h3>

class Login extends React.Component {
  state = {
    redirectToReferrer: false
  }
  login = () => {
    authenticator.authenticate(() => {
      this.setState(() => ({
        redirectToReferrer: true
      }))
    })
  }
  render() {
    const { from } = this.props.location.state || { from: { pathname: '/' } }
    const { redirectToReferrer } = this.state

    if (redirectToReferrer === true) {
      return <Redirect to = {from} />
    }

    return (
      <div>
        <p>You must log in to view the page</p>
        <button onClick = {this.login}>Log in</button>
      </div>
    )
  }
}

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render = {(props) => (
    fakeAuth.isAuthenticated === true
      ? <Component {...props} />
      : <Redirect to = {{
          pathname: '/login',
          state: { from: props.location }
        }} />
  )} />
)

const AuthButton = withRouter(({ history }) => (
  fakeAuth.isAuthenticated ? (
    <p>
      Welcome! <button onClick = {() => {
        fakeAuth.signout(() => history.push('/'))
      }}>Sign out</button>
    </p>
  ) : (
    <p>You are not logged in.</p>
  )
))

export default function AuthExample () {
  return (
    <Router>
      <div>
        <AuthButton/>
        <ul>
          <li><Link to = "/public">Public Page</Link></li>
          <li><Link to = "/protected">Protected Page</Link></li>
        </ul>
        <Route path = "/public" component = {Public}/>
        <Route path = "/login" component = {Login}/>
        <PrivateRoute path='/protected' component = {Protected} />
      </div>
    </Router>
  )
}

Однако проблема заключается в том, что я пытаюсь поместить разные скрипты в разные файлы и импортировать их. Из приведенного выше кода я переместил следующий код в скрипт с именем Authenticator.js, как показано ниже:

import React from 'react'
import { BrowserRouter as Route, Redirect } from "react-router-dom";

export const authenticator = {
    isAuthenticated: false,
    authenticate(cb) {
        this.isAuthenticated = true
        setTimeout(cb, 100) // fake async
    },
    signout(cb) {
        this.isAuthenticated = false
        setTimeout(cb, 100) // fake async
    }
}

export const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render = {(props) => (
    authenticator.isAuthenticated === true
      ? <Component {...props} />
      : <Redirect to = {{
          pathname: '/login',
          state: { from: props.location }
        }} />
  )} />
)

и импортировал его в исходный файл как:

import { PrivateRoute, authenticator } from './login/Authenticator'

Я также переместил класс Login как компонент в Login.js:

import React, { Component } from 'react'
import { authenticator } from './Authenticator'
import { Redirect } from "react-router-dom";

class Login extends Component {
    state = {
        redirectToReferrer: false
    }
    login = () => {
        authenticator.authenticate(() => {
            this.setState(() => ({
                redirectToReferrer: true
            }))
        })
    }
    render() {
        const { from } = this.props.location.state || { from: { pathname: '/' } }
        const { redirectToReferrer } = this.state

        if (redirectToReferrer === true) {
        return <Redirect to = {from} />
        }
        return (
        <div>
            <p>You must log in to view the page</p>
            <button onClick = {this.login}>Log in</button>
        </div>
        )
    }
}

export default Login

И импортировал его в скрипт:

import Login from './login/Login'

И конечно же я удалил эти методы из скрипта из туториала. В идеале, теперь, когда я перехожу по ссылке /protected, не входя в систему, я должен быть перенаправлен на страницу входа. ОДНАКО, я ничего не вижу. Однако я могу получить доступ, страница /login и вход в систему сохраняются, как и ожидалось. Я считаю, что проблема связана с классом Authenticator, но я ничего не менял, кроме перемещения кода в другой файл.

Вот мой окончательный основной скрипт с изменениями:

// import css
import 'bootstrap/dist/css/bootstrap.css'
import '@fortawesome/fontawesome-free/css/all.min.css'
import './css/ViewerApp.css'
// import js modules
import React, { Component } from 'react'
import { BrowserRouter as Router, Route, Link, withRouter } from "react-router-dom";
import 'jquery/dist/jquery.min.js'
import 'popper.js/dist/umd/popper.min.js'
import 'bootstrap/dist/js/bootstrap.min.js'
import Login from './login/Login'
import { PrivateRoute, authenticator } from './login/Authenticator'
// import TableView from './table/TableView'

const Public = () => <h3>Public</h3>
const Protected = () => <h3>Protected</h3>

class ViewerApp extends Component {
  render() {
    return (
      <Router>
        <ul style = {{ marginTop:'122px' }}>
          <li><Link to = "/public">Public Page</Link></li>
          <li><Link to = "/protected">Protected Page</Link></li>
        </ul>
        <AuthButton/>
        <Route path = "/public" component = {Public}/>
        <Route path = "/login" component = {Login}/>
        <PrivateRoute path='/protected' component = {Protected} />
      </Router>
    )
  }
}

const AuthButton = withRouter(({ history }) => (
  authenticator.isAuthenticated ? (
    <p>
      Welcome! <button onClick = {() => {
        authenticator.signout(() => history.push('/'))
      }}>Sign out</button>
    </p>
  ) : (
    <p>You are not logged in.</p>
  )
))

export default ViewerApp;

Кто-нибудь может помочь? Заранее спасибо.

куда вы поместили импортированный компонент <Login />?

r g 12.04.2019 10:52

@fard непосредственно перед импортом Authenticator.js

toing_toing 12.04.2019 10:54

Вам нужно выполнить его где-нибудь в вашем основном файле

r g 12.04.2019 10:55

Я сделал, я просто добавил код с компонентом кнопки авторизации в основной скрипт

toing_toing 12.04.2019 10:59

Любые ошибки, зарегистрированные в консоли?

cbdeveloper 12.04.2019 11:00

нет :( даже не предупреждение

toing_toing 12.04.2019 11:00

У вас нет /protected маршрута, только /tableview

r g 12.04.2019 11:02

извините, это должен быть /protected маршрут, я просто изменил название из туториала. я отредактирую пост

toing_toing 12.04.2019 11:04
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
8
161
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Похоже, у вас неправильный импорт в файле аутентификатора. Вы импортируете BrowserRouter вместо Route

import { BrowserRouter as Route, Redirect } from "react-router-dom";

Это должно быть

import { Route, Redirect } from "react-router-dom";

Спасибо, это сработало! Круто, но не могли бы вы объяснить, как это работало, потому что в основном скрипте я импортировал браузерный роутер, и почему он не работает для этого?

toing_toing 12.04.2019 11:13

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