功能isloggedin反应不起作用

时间:2020-10-30 20:18:55

标签: reactjs

我开始在React中学习和练习,我的想法是制作一个登录屏幕,在其中我调用rest api并将用户存储在内存中,登录后将用户重定向到Home。问题是我希望如果用户已登录,则应该无法查看登录屏幕。为此,我将“ isLogged”状态发送到“ login”组件,如果用户具有“ Logged”状态,我想将其重定向。问题在于状态未正确获得:

app.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom'
import './App.css';
import Login from './Pages/Login/Login'
import Logout from './Pages/Logout/Logout'
import Home from './Pages/Home/Home'


export default class App extends Component{
  constructor(){
    super();

    this.state = {
      loggedIn: "no-logueado",
      user:{},
    };

    this.handleLogin = this.handleLogin.bind(this);
    this.handleLogout = this.handleLogout.bind(this);
    this.loggedIn = this.loggedIn.bind(this);  

  }

  handleLogin(data){
    this.setState({
      loggedIn: "Logueado",
      user: data
    });
  }

  handleLogout(){
    this.setState({
      loggedIn: "no-logueado",
      user: {}
    });
  }

  isLoggedin(){
    const token = localStorage.getItem("authToken");
    if(this.state.loggedIn === "no-logueado" && token){
      this.setState({
        loggedIn: "Logueado",
        user: token
      });
    }
  }

  loggedIn(data){
    if(data === "Logueado"){
      window.location="/home";
    }
  }

async componentDidMount(){
  await this.isLoggedin();
}

  render() {
    
      return (
        <Router>
          <Route exact path="/" render={props => ( <Login {... props} handleLogin={this.handleLogin} loggedIn={this.state.loggedIn}/>)} />
          <Route exact path="/logout" render={props => ( <Logout {... props} handleLogout={this.handleLogout}/>)} />
          <Route exact path="/home" render={props => (<Home {... props} loggedIn={this.loggedIn} log={this.state.loggedIn}/>)} />


          <script src="https://unpkg.com/react/umd/react.production.min.js" crossorigin></script>

          <script
            src="https://unpkg.com/react-dom/umd/react-dom.production.min.js"
            crossorigin></script>

          <script
            src="https://unpkg.com/react-bootstrap@next/dist/react-bootstrap.min.js"
            crossorigin></script>

          <script>var Alert = ReactBootstrap.Alert;</script>
        </Router>
      );
  }
}

登录

import React, { Component } from 'react'
import Input from './Components/Input/input'
import Label from './Components/Label/Label'
import 'bootstrap/dist/css/bootstrap.min.css';
import './Login.css'
import {Container, Row, Col, Button} from 'react-bootstrap'

export default class Login extends Component {
    constructor(props) {
        super(props);

        this.state = {
            user:' ',
            password:' '
        }

        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleSuccessfullAuth = this.handleSuccessfullAuth.bind(this);
    }

    handleChange(name, value) {
        if(name==='username'){
            this.setState({user:value});
        } else {
            this.setState({password:value});
        }
    }

    async handleSubmit(){

            const requestOptions = {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({ 
                        email: this.state.user,
                        password:this.state.password
                    })
            };
            
            const response = await fetch('http://localhost:4000/login', requestOptions);
            console.log(response.ok);
            if(response.ok){
                const res = await response.json();
                localStorage.setItem("authToken", res.token)
                this.handleSuccessfullAuth(res);
            } else {
                console.log("token", localStorage.getItem("authToken"))
            }
             
        }

        handleSuccessfullAuth(data){
            this.props.handleLogin(data);
            this.props.history.push("/home");
        }
    
        componentDidMount(){
            console.log(this.props.loggedIn)
        }

    render(){
        return (       
            <div id="login-background">
                <Container>
                    <Row>
                        <Col xs={6}>
                            <Col xs={8}  className="back">
                                <h2 className="tittle-login">¡ Bienvenido !</h2>
                                <h2 className="tittle-login">{this.props.loggedIn}</h2>
                                <hr className="hr-design"></hr>
                            <Label text='Usuario'/>
                            <Input attribute= {{
                                id: 'username',
                                name:'username',
                                type:'text',
                                placeholder:'Ingrese su usuario ...',
                                className:'form-control'
                            }}
                            handleChange={this.handleChange}
                            />
                            <Label text='Contraseña'/>
                            <Input attribute= {{
                                id: 'password',
                                name:'password',
                                type:'password',
                                placeholder:'Ingrese su contraseña ...',
                                className:'form-control'
                            }}
                            handleChange={this.handleChange}
                            /><br></br>
                            <Button variant="primary" size="lg" block onClick={this.handleSubmit}>Iniciar Sesión</Button>{' '}
                            </Col>
                            <Col xs={4}>

                            </Col>
                                
                        </Col>
                        <Col>
                        
                        </Col>
                            
                    </Row>
                </Container>
            </div>
        )
    }
}


当我通过控制台查看状态如何到达“登录”状态时,尽管屏幕使我“登录”,但状态仍为“未登录”。

我认为我需要首先学习一些东西,或者我错过了一些东西,您能帮我吗?

Render "Logueado" but in console i obtain an "No-logueado" status

首页

import React, { Component } from 'react'
import Menu from '../../Components/Menu'


export default class Home extends Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div>
               <Menu/>
            </div>
        )
    }
}

1 个答案:

答案 0 :(得分:0)

如果用户已登录,则可以使用Redirect中的'react-router-dom'组件从登录页面重定向到主页。

只需在render()函数内添加条件返回。

  render() {
    if (this.props.loggedIn === STATE_LOGGED_IN) {
      return <Redirect path="/home" />;
    }

    return (
      <div id="login-background">
        <Container>
    ...

我还自由地重构了您的组件。我为您提供一些建议。

箭头功能

首先,您可以使用箭头函数代替需要绑定的类方法。箭头函数没有this关键字,因此不需要绑定。

  handleLogin = (data) => {
    this.setState({
      loggedIn: STATE_LOGGED_IN,
      user: data,
    });
  };

路线儿童

其次,我建议您使用children呈现的<Route>形式。它更干净,更容易阅读。

      <Router>
        <Route exact path="/">
          <Login handleLogin={this.handleLogin} loggedIn={this.state.loggedIn} />
        </Route>
        <Route exact path="/logout">
          <Logout handleLogout={this.handleLogout} />
        </Route>
        <Route exact path="/home">
          <Home loggedIn={this.state.loggedIn} />
        </Route>
      </Router>

请勿操作window.location

您还将注意到,我删除了名为window.location="/home"的函数。我建议您使用react-router-dom来更改位置,而不要直接修改window.location

使用常量字符串

最后,我建议您为'Logueado''no-logueado'字符串使用常量字符串。通过使用const,可以避免错误键入字符串的问题。

export const STATE_LOGGED_IN = 'Logueado';
export const STATE_LOGGED_OUT = 'no-logueado';

App.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import './App.css';
import Login from './Pages/Login/Login';
import Logout from './Pages/Logout/Logout';
import Home from './Pages/Home/Home';

export const STATE_LOGGED_IN = 'Logueado';
export const STATE_LOGGED_OUT = 'no-logueado';

export default class App extends Component {
  constructor() {
    super();

    this.state = {
      loggedIn: STATE_LOGGED_OUT,
      user: {},
    };
  }

  componentDidMount() {
    this.isLoggedin();
  }

  handleLogin = (data) => {
    this.setState({
      loggedIn: STATE_LOGGED_IN,
      user: data,
    });
  };

  handleLogout = () => {
    this.setState({
      loggedIn: STATE_LOGGED_OUT,
      user: {},
    });
  };

  isLoggedin = () => {
    const token = localStorage.getItem('authToken');
    if (this.state.loggedIn === STATE_LOGGED_OUT && token) {
      this.setState({
        loggedIn: STATE_LOGGED_IN,
        user: token,
      });
    }
  };

  render() {
    return (
      <Router>
        <Route exact path="/">
          <Login handleLogin={this.handleLogin} loggedIn={this.state.loggedIn} />
        </Route>
        <Route exact path="/logout">
          <Logout handleLogout={this.handleLogout} />
        </Route>
        <Route exact path="/home">
          <Home loggedIn={this.state.loggedIn} />
        </Route>
      </Router>
    );
  }
}

Login.js

请注意render方法中的条件返回。

import React, { Component } from 'react';
import Input from './Components/Input/input';
import Label from './Components/Label/Label';
import 'bootstrap/dist/css/bootstrap.min.css';
import './Login.css';
import { Container, Row, Col, Button } from 'react-bootstrap';
import { STATE_LOGGED_IN, STATE_LOGGED_OUT } from '../../App';
import { Redirect } from 'react-router';

export default class Login extends Component {
  constructor(props) {
    super(props);

    this.state = {
      user: ' ',
      password: ' ',
    };
  }

  componentDidMount() {
    console.log(this.props.loggedIn);
  }

  handleChange = (name, value) => {
    if (name === 'username') {
      this.setState({ user: value });
    } else {
      this.setState({ password: value });
    }
  }

  async handleSubmit = () => {
    const requestOptions = {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        email: this.state.user,
        password: this.state.password,
      }),
    };

    const response = await fetch('http://localhost:4000/login', requestOptions);
    console.log(response.ok);
    if (response.ok) {
      const res = await response.json();
      localStorage.setItem('authToken', res.token);
      this.handleSuccessfullAuth(res);
    } else {
      console.log('token', localStorage.getItem('authToken'));
    }
  }

  handleSuccessfullAuth = (data) => {
    this.props.handleLogin(data);
    this.props.history.push('/home');
  }

  render() {
    if (this.props.loggedIn === STATE_LOGGED_IN) {
      return <Redirect path="/home" />;
    }

    return (
      <div id="login-background">
        <Container>
          <Row>
            <Col xs={6}>
              <Col xs={8} className="back">
                <h2 className="tittle-login">¡ Bienvenido !</h2>
                <h2 className="tittle-login">{this.props.loggedIn}</h2>
                <hr className="hr-design"></hr>
                <Label text="Usuario" />
                <Input
                  attribute={{
                    id: 'username',
                    name: 'username',
                    type: 'text',
                    placeholder: 'Ingrese su usuario ...',
                    className: 'form-control',
                  }}
                  handleChange={this.handleChange}
                />
                <Label text="Contraseña" />
                <Input
                  attribute={{
                    id: 'password',
                    name: 'password',
                    type: 'password',
                    placeholder: 'Ingrese su contraseña ...',
                    className: 'form-control',
                  }}
                  handleChange={this.handleChange}
                />
                <br></br>
                <Button variant="primary" size="lg" block onClick={this.handleSubmit}>
                  Iniciar Sesión
                </Button>{' '}
              </Col>
              <Col xs={4}></Col>
            </Col>
            <Col></Col>
          </Row>
        </Container>
      </div>
    );
  }
}