Se devuelve un nuevo componente después del inicio de sesión, pero tanto el componente de inicio de sesión como el componente de inicio se ven en la página. Necesito devolver el componente de inicio sin el componente de inicio de sesión. Soy nuevo en React y todavía estoy tratando de entender el retorno y las rutas en React.

Este es el componente de mis páginas que devuelve Inicio de sesión o Inicio según this.state.redirect1.

    import React, { Component } from 'react';
    import { Redirect } from 'react-router-dom';
    import '../../App.css';
    import Login from '../Login';
    import Home from '../Home';
    import Header from './Header';
    import Footer from './Footer';


    class Pages extends Component {
      constructor(props) {
        super(props)

        this.state = {
          redirect: false,
        }

  }
  handleClick() {
    this.state.redirect = true;
    console.log(this.state.redirect);
  }
  changeRedirect =() =>{
    this.state.redirect = true;
    console.log(this.state.redirect);
    this.forceUpdate()

  }
  renderRedirect = () => {
    if(this.props.redirect1){
      return <Home/>
    }
    else{
      return <Login/>
    }
  }

  render() {

    return (

      <div className="mh-100 PgWidth">
      {this.renderRedirect()}
      </div>
    )
  }
}
export default Pages

A continuación se muestran mis componentes de inicio de sesión, inicio y aplicación

Login.js

import React, { Component } from 'react'
import Axios from 'axios';
import Pages from './common/Pages'
import { Redirect } from 'react-router-dom';

class Login extends Component {


    constructor(props) {
        super(props)

        this.state = {
            username: '',
            password: '',
            redirect: false
        }
    }

    handleUsername = (event) => {
        this.setState({
            username: event.target.value
        })
    }

    handlePassword = (event) => {
        this.setState({
            password: event.target.value
        })
    }
    renderRedirect = () => {
        if (this.state.redirect) {
            console.log("from render redirect");
            return <Pages redirect1={this.state.redirect} />
        }
    }


    formSubmitHandler = event => {
        let formdata = new FormData();
        formdata.append("username", this.state.username);
        formdata.append("password", this.state.password);
        Axios.post("/auth/local",{
            "name":this.state.username,
            "password": this.state.password
           })
            .then(res => {
                if (res) {
                    console.log(res);
                    this.setState({ redirect: true });


                }


            })
        event.preventDefault() // used to keep the form data as entered even after the submit
    }

    render() {

        const { username, password } = this.state
        return (

            <div className="p-5">
            { this.renderRedirect() }
                <h3>Sign-In</h3>
                <form onSubmit={this.formSubmitHandler}>
                    <div className="form-group row">
                        <label htmlFor="inputEmail3" className="col-sm-2 col-form-label">Username</label>
                        <div className="col-sm-10">
                            <input type="text" value={username} onChange={this.handleUsername}
                                className="form-control" id="inputEmail3" placeholder="Username" />
                        </div>
                    </div>
                    <div className="form-group row">
                        <label htmlFor="inputPassword3" className="col-sm-2 col-form-label">Password</label>
                        <div className="col-sm-10">
                            <input type="password" value={password} onChange={this.handlePassword}
                                className="form-control" id="inputPassword3" placeholder="Password" />
                        </div>
                    </div>

                    <div className="form-group row">
                        <div className="col-sm-2">Checkbox</div>
                        <div className="col-sm-10">
                            <div className="form-check">
                                <input className="form-check-input" type="checkbox" id="gridCheck1" />
                                <label className="form-check-label" htmlFor="gridCheck1">
                                    Example checkbox
                                </label>
                            </div>
                        </div>
                    </div>
                    <div className="form-group row">
                        <div className="col-sm-10">
                            <button type="submit" onClick={this.formSubmitHandler} className="btn btn-primary">Sign in</button>
                        </div>
                    </div>
                </form>

            </div>

        )
    }
}

export default Login

Home.js

import React, { Component } from 'react'
import '../App.css';


export class Home extends Component {

  componentDidMount(){
    console.log("home component mount");
  }



  render() {
    return (
      <div>
        <h1>The page has been routed</h1>
      </div>
    );
  }
}

export default Home

App.js

import React, { Component } from 'react';
import './App.css';
import Header from './components/common/Header';
import Footer from './components/common/Footer';
import Pages from './components/common/Pages';

class App extends Component {
  render() {
    return (

      <div className="App container-fluid bg-light w-75">
      <div className="row justify-content-md-center">
        <div className="col m-0 p-0">
          <Header/>
            <div className="">
            <Pages/>
            </div>
          <Footer/>
        </div>
      </div>
    </div>
    );
  }
}

export default App;
1
Pavan Sista 10 may. 2019 a las 09:52

3 respuestas

La mejor respuesta

El problema está en esta línea:

{ this.renderRedirect() }

Una vez que la redirección sea verdadera, mostrará primero la página de inicio y luego el componente de inicio de sesión.

La solución a su problema es: administre el bool de redireccionamiento solo en el componente de página y pase una función para actualizar al componente de inicio de sesión para actualizar su valor y decidir el componente en función de eso.

Cambios:

1- definido redirect: false en el componente Páginas.

2- Una función para cambiar su valor en el componente Páginas:

updateValue = (value) => {
  this.setState({ redirect: true })
}

3- Función de paso al componente de inicio de sesión:

renderRedirect = () => {
  if(this.props.redirect1) {
    return <Home/>
  }
  else{
    // =====> here
    return <Login updateValue={this.updateValue} />
  }
}

4- Después de iniciar sesión correctamente, llame a esta función y renderice el componente de inicio:

formSubmitHandler = event => {
  event.preventDefault();

  let formdata = new FormData();
  formdata.append("username", this.state.username);
  formdata.append("password", this.state.password);

  Axios.post("/auth/local",{
    "name":this.state.username,
    "password": this.state.password
  })
  .then(res => {
    if (res) {
       // =======> here
       this.props.updateValue(true)
    }
  })
}

5- Eliminar esta línea del componente de inicio de sesión:

{ this.renderRedirect() }

Problema con el código actual:

Está administrando la sesión de inicio de sesión utilizando la variable de estado, por lo que después de actualizar la página, volverá a mostrar la página de inicio de sesión, no la página de inicio. Por lo tanto, es mejor almacenar el valor en localStorage y leer su valor en el componente de la página para decidir el valor inicial de redirect.

Sugerencia:

En lugar de decidir la ruta / componente con boolean, es mejor usar < strong> react-router para estructurar / administrar mejor la aplicación.

2
Mayank Shukla 10 may. 2019 a las 07:13

Intenta devolverlo en render:

    import React, { Component } from 'react';
    import { Redirect } from 'react-router-dom';
    import '../../App.css';
    import Login from '../Login';
    import Home from '../Home';
    import Header from './Header';
    import Footer from './Footer';


    class Pages extends Component {
      constructor(props) {
        super(props)

        this.state = {
          redirect: false,
        }

  }
  handleClick() {
    this.state.redirect = true;
    console.log(this.state.redirect);
  }
  changeRedirect =() =>{
    this.state.redirect = true;
    console.log(this.state.redirect);
    this.forceUpdate()

  }

  render() {

  if(this.props.redirect){
    return (
      <div className="mh-100 PgWidth">
        <Home/>
      </div>
    )
  } else {
    return (
      <div className="mh-100 PgWidth">
        <Login/>
      </div>
    )
  }
}
export default Pages;
1
Robert Hovhannisyan 10 may. 2019 a las 07:07

Puedes hacerlo así

<div className="mh-100 PgWidth">
  {this.props.redirect1&&<Home/>}
  {!this.props.redirect1&&<Login />}
</div>

Pero, la mejor manera de hacer esto es usar el enrutador de reacción y administrar el estado de reacción global

0
lm1010 10 may. 2019 a las 07:27