IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

React Discussion :

allez-retour : d'une page react -> symfnoy et symfony -> react


Sujet :

React

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2020
    Messages
    280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2020
    Messages : 280
    Par défaut allez-retour : d'une page react -> symfnoy et symfony -> react
    Bonsoir,

    je fais uns site / exercice pour apprendre Symfony et ...plein d'autres choses
    j'ai donc un peu de tout: du React, du twig, api plateForm...

    Ma page d'accueil contient la div pour intégrer la partie gérée par React
    C'est le seul endroit où je fais du React... c'est pas génial, il aurait fallu le faire pour tout le site , mais je voulais apprendre à me servir de tout et j'ai donc fais des pages en Twig

    Viens le moment où une modale ( toujours dans les composants react ) demande de se connecter pour continuer.
    Alors je clique sur un lien qui contient le route /login de Symfony. je peux alors me connecter. Puis je suis redirigé vers la page d'accueil,
    qui affiche une liste de Card et un formulaire de recherche.

    Pour l'instant , donc il n'y a pas de problèmes, sauf que:
    avant de me connecter , j'étais sur une card ( celle que j'avais choisi dans la page d'accueil ) et je souhaiterais être redirigé sur cette card !

    Ce n'est pas forcément impossible, après réflexion:
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    ReactDOM.render(<HelloApp />, document.getElementById("root"))

    Si j'arrive à renseigner l'id de la card dans ce composant, j'arrive directement sur ma card !

    Dans mon react:
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import React from 'react'
     
    const Modale = ({hide, visible, animalId}) => {
     
        const idTab = animalId.split('/')
        const url = '/login/' + idTab[idTab.length - 1]
        return (visible && <div className='bg-warning'>
            <h1>vou devez vous connecter pour faire cette opération</h1>
            <a href={url}>Se connecter</a>
            <div onClick={hide}>x</div>
        </div>)
     
    } 
     
    export default Modale

    J'ai réussi à renvoyé l'id de ma card du coup ( en modifiant des routes et render... tout un programme) :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    if (document.getElementById("root")) {
        const id = parseInt(document.getElementById('root').dataset.id, 10)
        if (id === 0) {
            ReactDOM.render(<HelloApp />, document.getElementById("root"))
     
        } else {
            ReactDOM.render(<HelloApp  id={id}/>, document.getElementById("root"))
        }
    }

    Et je reviens donc sur ma card que j'avais quittée...
    Avec une erreur en console:
    Can't perform a React state update on an unmounted component.
    Je soupçonne un problème avec la modale que j'ai quittée pour me connecter... mais j'avoue ne pas comprendre

    Laurent.

  2. #2
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2020
    Messages
    280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2020
    Messages : 280
    Par défaut
    Alors j'ai avancé sur mon erreur et je crois savoir pourquoi !

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    if (document.getElementById("root")) {
        const id = parseInt(document.getElementById('root').dataset.id, 10)
        if (id === 0) {
            ReactDOM.render(<HelloApp />, document.getElementById("root"))
     
        } else {
            ReactDOM.render(<HelloApp  id={id}/>, document.getElementById("root"))
        }
    }

    Du coup, puisque je récupère bien un id alors je vais monter le composant <HelloApp id={id} />
    Puis le rendu de <HelloApp id={id} />:
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    render() {
            return <div>
                    {this.state.onlyOne && <AnimalCard  animalId={this.state.animalId}/>}
                    {!this.state.onlyOne && <FormResearch wantName={this.handleIfJustName} onResult={this.handleResult}/>}
                    {!this.state.onlyOne && <CardList wantOneAnimal={this.handleOneAnimal} url={this.state.url} />}
                </div> 
        }

    Je vais monter tout ça avec dans le composant <CardList />:
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    findAnimalList = (url) => {
            fetch(url)
            .then( response => { 
                return response.json() 
            } 
            )
            .then( resp => {
                this.setState({
                    animalList: resp["hydra:member"],
                    animalsNumber: resp["hydra:totalItems"],
                    view: resp["hydra:view"],
                })
            })
        }
     
        componentDidMount() {
            this.findAnimalList(this.state.url)
        }

    Je fais un fetch sur l'api pour récupérer une liste d'animaux

    Mais pendant ce temps sur mon <HelloApp id={id} />:
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    componentDidMount() {
            if (this.props.id) {
                this.setState({
                    animalId: '/api/animals/' + this.props.id,
                    onlyOne: true
                })
            }
        }

    Ce qui provoque un nouveau rendu et un démontage du composant <CardList /> alors qu'il n'a pas fini de récupérer la liste.
    Et affichage de l'erreur comme quoi , on ne peut pas mettre à jour un composant démonté !!

    En espérant que j'ai bien compris.

    Dans la documentation de React, on donne l'exemple du timer que je comprends bien, mais dans mon cas , je dois arrêter un fetch
    Et mon niveau ne me permet pas de savoir quoi mettre dans le componentWillUnmount(), vraiment aucune idée...
    Si je pouvais avoir une idée de la marche à suivre pour parvenir à mes fins,
    merci

    Laurent.

  3. #3
    Expert confirmé

    Avatar de -Nikopol-
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2013
    Messages
    2 174
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2013
    Messages : 2 174
    Billets dans le blog
    5
    Par défaut
    tu es avec les hook ou avec les classes ? faire cohbiter les deux n'est pas forcement une bonne idée (maintenabilité, cohérence toussa toussa...)
    pour les hook il te faut un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    useEffect(()=>{
       //setMyvar(...)
    },[myVar]);
    ce qui aura pour effet de ne mettre à jour ton state qu'une fois

  4. #4
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2020
    Messages
    280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2020
    Messages : 280
    Par défaut
    En fait , j'ai commencé react avec des classes ( parce que les tutos sur react commencent avec les classes ) puis je suis passé aux hooks ...!
    Donc j'ai des composants fonctionnels et des composants de classe, c'est à cause de l'évolution de mes connaissances en React.

    Je me rends compte que j'ai deux composants qui font des requêtes et qui sont démontés avant la fin de leurs requêtes.

    Pour un composant fonctionnel ou de classe , je vais utiliser dans les deux cas l'objet AbortController
    Je commence par le composant de classe je déclare:
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    const controller = new AbortController()
    const signal = controller.signal
     
    class CardList extends React.Component
    {
        constructor(props) {
            super(props)
            this.state  = {
                ...init
            }
        }
     
        findAnimalList = async (url) => {
            console.log('je fais le fetch')
            const response = await fetch(url, {signal})
            const rep = await response.json()
            this.setState({
                animalList: rep["hydra:member"],
                animalsNumber: rep["hydra:totalItems"],
                view: rep["hydra:view"]
            })
        }

    puis dans le componentWillUnmount:
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    componentWillUnmount() {
            controller.abort()
        }

    Et ça fonctionne !

    Dans mon composant fonctionnel le problème se situe dans le useEffetc:
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for (const select of inputFields["select"]) {
            useEffect ( () => {
                fetch('api/' + select["table"])
                .then( response => response.json())
                .then( 
                    result => {
                        setOptions( state => ({...state, [select["primaryEntity"]]: extractDatasSelect(result["hydra:member"])}))
                    },
                    error => setError(error)
                    )
            }, [])
        }

    Au passage , faut-il faire un for avec un useEffect à l'intérieur ou un useEffect avec un for ... ?

    Ensuite, il suffirait de déclarer un const controller= useRef( new AbortController() )
    Puis un
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    for (const select of inputFields["select"]) {
            useEffect ( () => {
                fetch('api/' + select["table"], {signal: controller.current.signal})
                .then( response => response.json())
                .then( 
                    result => {
                        setOptions( state => ({...state, [select["primaryEntity"]]: extractDatasSelect(result["hydra:member"])}))
                    },
                    error => setError(error)
                    )
            }, [])
        }
     
     useEffect ( () => () => controller.current.abort(), [])

    Du coup, je ferais plutôt un for avec un useEffect à l'intérieur.
    Mais ça ne fonctionne pas!

    La solution ne doit pas être loin !

  5. #5
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2020
    Messages
    280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2020
    Messages : 280
    Par défaut
    Bonjour, je vais poser la question plus simplement:
    dans un script React du genre:
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for (const select of inputFields["select"]) {
            useEffect ( () => {
                fetch('api/' + select["table"])
                .then( response => response.json())
                .then( 
                    result => {
                        setOptions( state => ({...state, [select["primaryEntity"]]: extractDatasSelect(result["hydra:member"])}))
                    },
                    error => setError(error)
                    )
            }, [])
        }

    comment intégrer l'objet new AbortController() pour stoper les requêtes en cours ???

Discussions similaires

  1. Réponses: 1
    Dernier message: 07/10/2009, 15h32
  2. Fonction "retour" dans une page
    Par literati dans le forum Débuter
    Réponses: 2
    Dernier message: 06/12/2007, 14h02
  3. Garder la position d'un scroll au retour sur une page
    Par Leopardi dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 28/09/2007, 11h49
  4. [AJAX] Retour a une page précédente
    Par HWICE dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 16/07/2007, 14h48
  5. retour vers une page inexistante
    Par ph_anrys dans le forum Langage
    Réponses: 2
    Dernier message: 16/03/2006, 00h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo