1
votes

Le nouveau composant est renvoyé mais le composant précédent reste le même dans ReactJs

Un nouveau composant est renvoyé après la connexion, mais le composant de connexion et le composant d'accueil sont affichés sur la page. Je dois renvoyer le composant domestique sans composant de connexion. Je suis nouveau dans React et j'essaie toujours de comprendre les retours et les itinéraires dans React.

Il s'agit du composant mes pages qui renvoie soit Login, soit Home en fonction de this.state.redirect1.

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;

Vous trouverez ci-dessous mes composants de connexion, d’accueil et d’application.

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

Home.js

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

App.js p>

    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


2 commentaires

Cela pourrait vous aider.


Mais si j'utilise Redirection, je n'obtiendrai pas de composant d'en-tête ou de pied de page car il redirigera vers le composant d'accueil qui n'a pas de pied de page ou d'en-tête.


3 Réponses :


1
votes

Essayez de le renvoyer dans le rendu:

    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;


9 commentaires

Je suis désolé, mais il en résulte le même problème.


Hmm, ok quoi maintenant?


Je pense que vous avez une faute de frappe. Je n'ai pas trouvé redirect1 dans votre code


redirect1 est un accessoire du composant de connexion. Désolé


Oui mais vous ne le définissez pas quelque part. Pour commencer, vous devez définir direct1 dans Pages en tant qu'état et seulement après cela, utilisez-le dans d'autres pages comme accessoires


Essayez simplement de changer l'état redirect1 en redirect dans Your Pages.js, voyez ce que sera


Puisque la valeur initiale de redirect1 n'est pas définie, cela ne fera aucune différence. J'ai créé un accessoire en tant que return dans le composant de connexion.


Oh, je suis heureux que tu aies la réponse, question très intéressante :)


Merci @Robert. Vous pouvez le voter si vous le souhaitez :)



2
votes

Le problème est dans cette ligne:

{ this.renderRedirect() }

Une fois que la redirection sera vraie, elle affichera d'abord la page d'accueil, puis le composant de connexion.

La solution à votre problème est: Gérez le booléen de redirection dans le composant Page uniquement, et passez une fonction à mettre à jour au composant Login pour mettre à jour sa valeur et décider du composant en fonction de cela.

Modifications:

1- défini redirect: false dans le composant Pages.

2- Une fonction pour changer sa valeur dans le composant Pages:

XXX

3- Passez la fonction au composant de connexion:

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)
    }
  })
}

4- Après une connexion réussie, appelez cette fonction et affichez le composant Home:

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

5- Supprimer cette ligne du composant de connexion:

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

Problème avec le code actuel: p >

Vous gérez la session de connexion à l'aide de la variable d'état, donc après avoir actualisé la page, elle affichera à nouveau la page de connexion et non la page d'accueil. Il vaut donc mieux stocker la valeur dans localStorage et lire sa valeur dans le composant de page pour décider de la valeur initiale de redirect .

Suggestion:

Au lieu de décider de la route / du composant en utilisant boolean , mieux vaut utiliser react-router pour une meilleure structuration / gestion de l'application.


3 commentaires

Merci, j'ai également ajouté this.forceUpdate () dans updateValue (value) à la fin,


Je pense que sans cela, cela devrait fonctionner. Cela ne fonctionne-t-il pas sans forceUpdate?


Non ce n'est pas. La valeur de la redirection passe à "true", mais le composant n'a pas été rendu.



0
votes

Vous pouvez le faire comme ceci

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

Mais, la meilleure façon de le faire est d'utiliser le routeur de réaction et de gérer l'état de réaction global


0 commentaires