javascript - 当分解成组件时,登录表单 React 不起作用

标签 javascript reactjs ecmascript-6

作为新手Reacteur,我一直在关注这个tutorial使用 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>
  )
}

H但是,问题是当我尝试将不同的脚本放在不同的文件中并导入它们时。从上面的代码中,我将以下代码移动到名为 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.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;

有人可以帮忙吗?提前致谢。

最佳答案

您的身份验证器文件中似乎有错误的导入。您正在导入 BrowserRouter 而不是 Route

从“react-router-dom”导入 { BrowserRouter 作为路由,重定向};

应该是

从“react-router-dom”导入{路由,重定向};

关于javascript - 当分解成组件时,登录表单 React 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55647836/

相关文章:

javascript - 跨多个组件重用 React.useCallback() 函数

javascript - setTimeout 非法调用 TypeError : Illegal invocation

javascript - 使用 Array.filter 比较两个数组并根据共同值推送到新数组

javascript - ES6 在 html 中导入 vs &lt;script src>

javascript - react .js : how to decouple jsx out of JavaScript

javascript - moment 在 Internet Explorer 和 Safari 上返回无效日期

reactjs - React 表中的日期时间列

javascript - 未捕获的不变违规 : Maximum update depth exceeded

javascript - 在 Typescript 中使用 Array.from 收到的函数未定义错误

Javascript 全选复选框突然不起作用