Аутентификация при входе в react и laravel не регистрируется

#javascript #reactjs #laravel #react-router

#javascript #reactjs #laravel #react-маршрутизатор

Вопрос:

Я новичок в react и react router, и я пытаюсь выполнить аутентификацию с помощью laravel react и react router. Страница перенаправляется в желаемое место назначения, поскольку URL изменяется при нажатии кнопки отправки, но, похоже, возникает ошибка, которую я не могу понять. Когда я вручную перезагружаю страницу, компонент, кажется, отображается, но при нажатии кнопки отправки / отправке формы реакция выдает приведенную ниже ошибку.

Ошибка в консоли

 Warning: Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state. app.js:39442:7
The above error occurred in the <LoginPage> component:
    in LoginPage (created by Route)
    in Route (created by withRouter(LoginPage))
    in withRouter(LoginPage) (created by Route)
    in Route (created by RouterComponent)
    in Switch (created by RouterComponent)
    in Router (created by BrowserRouter)
    in BrowserRouter (created by RouterComponent)
    in RouterComponent
    in Provider

Consider adding an error boundary to your tree to customize error handling behavior.
Error: LoginPage(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null. app.js:38991:15
Source map error: SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
Resource URL: http://127.0.0.1:8000/js/app.js
Source Map URL: popper.js.map[Learn More]
  

Компонент входа в систему

 import React, { Component } from 'react'
import '../../../public/admin/css/bootstrap.min.css';
import '../../../public/admin/css/themify-icons.css';
import '../../../public/admin/css/styles.css';
import { withRouter, Redirect } from 'react-router-dom';
class LoginPage extends Component {
    constructor(props) {
        super(props);
        this.state = {
            email: '',
            password: '',
            token: '',
            loggingIn: false,
            error: []
        }
        this.changeVal = this.changeVal.bind(this);
        this.login = this.login.bind(this);
    }
    componentDidMount() {
        this.setState({
            token: document.getElementById("csrf-token").getAttribute("content")
        })
    }
    changeVal(e) {
        this.setState({
            [e.target.name]: e.target.value
        })
    }
    login(e) {
        e.preventDefault();
        let arr = {
            email: this.state.email,
            password: this.state.password,
            token: this.state.token
        };
        let route = e.target.getAttribute('action');
        axios.post(route, arr).then(response => {
            localStorage.setItem('userId', response.data[0].id);
            localStorage.setItem('loggedIn', "true");
            this.props.history.push('/admin/dashboard');
        }).catch(error => {
            if(localStorage.getItem('userId') !== null) return localStorage.removeItem('userId');
            if(localStorage.getItem('loggedIn') !== null) return localStorage.removeItem('loggedIn');
            console.log(response.error);
        })
    }
    render() {
        if ((localStorage.getItem('loggedIn') === "true")) return this.props.history.push('/admin/dashboard');
        return (
            <div className="login-area">
                <div className="container">
                    <div className="login-box ptb--100">
                        <form method="POST" onSubmit={this.login} action="/api/login">
                            <input type="hidden" name="_token" value={this.state.token} />
                            <div className="login-form-head">
                                <h4>Sign In</h4>
                            </div>
                            <div className="login-form-body">

                                <div className="form-gp">
                                    {
                                        /*     this.props.errors.map(item => {
                                            return (
                                                <span key={item} className="text-danger d-block" role="alert">
                                                    <strong>{item}</strong>
                                                </span>
                                            )
                                        }) */
                                    }
                                </div>
                                <div className="form-gp">
                                    <input id="email" type="email" className={"form-control "} name="email" autoFocus value={this.state.email} onChange={this.changeVal} />
                                    <i className="ti-email"></i>
                                </div>

                                <div className="form-gp">
                                    <input id="password" type="password" className={"form-control"} name="password" value={this.state.password} onChange={this.changeVal} />
                                    <i className="ti-lock"></i>
                                </div>

                                <div className="form-gp">
                                    <a href="/password/reset">Forgot Password?</a>
                                </div>
                                <div className="submit-btn-area">
                                    <button id="form_submit" type="submit" >{(this.props.loggedIn) ? "Submit Form" : "Please fill form"}  <i className="ti-arrow-right"></i></button>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        )
    }
}
export default (withRouter(LoginPage));
  

Компонент маршрутизатора

 import React,{Component} from 'react';
import IndexPage from './components/IndexPage';
import ContactPage from './components/ContactPage';
import CmsPage from './components/CmsPage';
import ErrorPage from './components/ErrorPage';
import ThanksPage from './components/ThanksPage';
import LoginPage from './components/LoginPage';
import Dashboard from './components/Dashboard';
import withRoot from './Root';
import {PrivateRoute} from './layouts/helpers';
import {BrowserRouter as Router,Route,Switch} from 'react-router-dom';
class RouterComponent extends Component{
    render(){
        return (
            <Router basename={'/'}>
                <Switch> 
                    <Route path="/" exact component={withRoot(IndexPage)} />
                    <Route path="/contact" exact component={withRoot(ContactPage)} />
                    <Route path="/thanks" exact component={withRoot(ThanksPage)} />
                    <Route path="/page/:id" exact component={withRoot(CmsPage)} />
                    <Route path="/page/:id/subpage/:subId" exact component={withRoot(CmsPage)} />
                    <Route path="/admin/login" exact component={LoginPage} />
                    <PrivateRoute authed={(localStorage.getItem('loggedIn') === "true")} path='/admin/dashboard' component={Dashboard} />
                    <Route component={ErrorPage} />
                </Switch>
            </Router>
        )
    }
}
export default RouterComponent;
  

Защищенный маршрут

 export function PrivateRoute ({component: Component, authed, ...rest}) {
    return (
      <Route exact
        {...rest}
        render={(props) => authed === true
          ? <Component {...props} />
          : <Redirect to={{pathname: '/admin/login', state: {from: props.location}}} />}
      />
    )
  }
  

Панель мониторинга или куда перенаправляется логин

 import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';
class Dashboard extends Component {
  constructor(props){
    super(props);
    this.state = {
      token:'',
      userId: localStorage.getItem('userId'),
      loggedIn: (localStorage.getItem('loggedIn') === "true")
    }
    this.logout = this.logout.bind(this);
  }
  componentDidMount() {
      this.setState({
          token: document.getElementById("csrf-token").getAttribute("content")
      })
  }
  logout(e) {
    e.preventDefault();
    let route = e.target.getAttribute("action");
    let arr = {
      token : this.state.token
    }
    axios.post(route,arr).then(response => {
      localStorage.removeItem('loggedIn');
      localStorage.removeItem('userId');
      this.props.history.push('/admin/login');
    }).catch(error => {
      console.log(error);
    })
    console.log("route ->"   route);
  }
  render() {
    return (
      <>
        {localStorage.getItem('userId')}
        <form action="/api/logout" className="d-inline-block" method="post" onSubmit={this.logout}>
          <input type="hidden" name="_token" value={this.state.token} />
          <button type="submit" className="btn btn-danger btn-sm">Logout</button>
        </form>
      </>
    )
  }
}
export default (withRouter(Dashboard));
  

Приветствуется любое изменение кода или практическая реализация

Комментарии:

1. Пожалуйста, добавьте ошибку в виде текста, а не изображения

Ответ №1:

Решить эту проблему легко.

1. Сначала удалите следующую логику из компонента render in login

 if ((localStorage.getItem('loggedIn') === "true")) return this.props.history.push('/admin/dashboard');
  

2. Добавьте метод жизненного цикла в компонент login

   componentDidUpdate(){
   if ((localStorage.getItem('loggedIn') === "true")) 
    return this.props.history.push('/admin/dashboard');
}
  

Это потому, что рендеринг в React должен быть чистым. Но в вашем компоненте login вы хотите перенаправить на dashboard, пока он все еще пытался отобразить текущий компонент.Такого рода действия обычно не разрешены. Лучший способ перенаправить пользователей на панель мониторинга, если они вошли в систему, — добавить componentDidUpdate.

Примечание: React уже опубликовал 16.8. Вы можете использовать hook вместо class component.Если вы используете hook, вы можете сделать это следующим образом:

     useEffect(()=>{
if(localStorage.getItem('loggedIn')amp;amp;localStorage.getItem('loggedIn')==='true){
props.history.push('/admin/dashboard')
}
})
  

Надеюсь, это решит вашу проблему.
Спасибо.

Комментарии:

1. Я получаю эту ошибку Ошибка: превышена максимальная глубина обновления. Это может произойти, когда компонент повторно вызывает setState внутри componentWillUpdate или componentDidUpdate. React ограничивает количество вложенных обновлений, чтобы предотвратить бесконечные циклы.

2. вы использовали this.setState в componentDidUpdate? Выполнение этого приведет к неограниченному обновлению этого компонента.