Bonjours,
Je vais essayer d'exposer mon problème clairement !
Je fais un exercice, qui me permet de mettre tous mes apprentissages en exemple: il concentre tout ce que j'apprends au jour le jour...
Du coup, j'ai des composants React: fonctionnels et de classe
Je sais , ce n'est pas super, mais c'est fonction de mon niveau, et au moins j'ai des des exemples dans mon exercice, et ce sont les miens: plus facile à réviser.
Et j'ai aussi des pages en Symfony/twig et des pages en React ( même commentaire que plus haut ).
Je vais donc vous expliquer comment est faite ma page d'accueil.
- en header, des liens pour gérér les utilisateurs de l'application (le CRUD) . Ces liens mènent vers des pages twig appelées par un Controler ( du Symfony classique )
- en body de la page d'accueil, l'application elle-même: le React, consultation de fiches sur des animaux ( BDD ), et CRUD en React
Un utilisateur de l'application peut être connecté ou non.
Je prends le cas où il est connecté. Mon composant de base (une classe HelloApp):
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 render() { return <div> {this.state.onlyOne && !this.state.addAnimal && <AnimalCard animalId={this.state.animalId}/>} {!this.state.onlyOne && !this.state.addAnimal && <div> <button className="btn btn-primary" onClick={ () => { this.setState({addAnimal: true})}}>Ajouter un animal</button> <Form context="fullResearch" onResult={this.handleResult} field="animal"/> <CardList wantOneAnimal={this.handleOneAnimal} url={this.state.url} /> </div>} {this.state.addAnimal && <Form context="creation" field="animal"/>} </div> }
qui dans ce cas , va afficher un formulaire de recherche (composant Form ) et une liste des résultats (CardList )
Au départ , il n'y a pas de recherche: on affiche tout avec une pagination.
il y a donc dans le composant CardList une requête au montage. Et dans le formulaire, il y a des requêtes pour élaborer des sections dont les options proviennent de la BDD
On choisi un animal de la liste et on voudrait le modifier. On se sert aussi du Form pour l'édition.
Mon composant Form est un peu long , dans le return final j'ai entre autre:
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 {showList && props.field ==='worldPopulation' && <HelloApp id={props.animalId}/>} {showList && props.field ==='animal' && <HelloApp id={props.id}/>}
Mon HelloApp va avoir une props id et au montage de HelloApp:
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 componentDidMount() { if (this.props.id) { let animalId = prepareId(this.props.id) this.setState({ animalId: animalId, onlyOne: true }) } }
HelloApp va donc afficher directement la fiche de l'animal qu'on a modifié. Au passage , il faut stopper les requêtes des composants CardList et Form, car,
ils sont montés lorsque j'appelle HelloApp puis démontés ( puisqu'on n'affiche que AnimalCard au final ) et les requêtes ne sont pas terminées
( React ne pourra dobnc pas faire de update si le composant est Démonté avant la fin de la requête ).
J'utilise l'API AbortController.
Tout fonctionne, dans ce cas !
Mais le cas où l'utilisateur n'est pas connecté.
Je dois lui demander de se connecter, un composant Modale est prévue à cet effet ( c'est le même pour la destruction )
Le problème: comment envoyer l'utilisateur sur la page twig ( authentification classique de Symfony )
J'y vais le plus simplement ( naïvement ? ) dans mon Modale
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
23
24
25
26 import React from 'react' const Modale = ({hide, visible, animalId, context, del}) => { const handleClick = () => { hide() del() } const idTab = animalId.split('/') const url = '/login/' + idTab[idTab.length - 1] return (visible && <div className='bg-warning'> {context === "change" && <div> <h1>vou devez vous connecter pour faire cette opération</h1> <a href={url}>Se connecter</a> </div>} {context === "destruction" && <div> <h1>Vous voulez détruire cette fiche ?</h1> <button onClick={handleClick}>oui</button> </div>} <div onClick={hide}>x</div> </div>) }
Je rajoute l'id de l'animal à la fin de l'url!
En effet, une fois identifié, l'utilisateur revient sur la page d'accueil:
Code twig : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 {% extends 'layouts/base.html.twig' %} {% block body %} <div id="root" data-id="{{id}}"></div> {% endblock %}
Et du coup mon script:
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 import './bootstrap'; import React from 'react' import ReactDOM from 'react-dom' import HelloApp from './ReactApp/HelloApp' 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 puisque mon HelloApp possède une props id, alors on affiche directement la fiche de l'animal qu'on voulait modifier avant authentification.
C'est pas mal de bidouillage, mais naviguant entre des pages tiwg et des pages React, je ne voyais pas comment faire pour afficher obligatoirement
la page de l'animal au lieu de la page d'accueil avec la liste ( car l'utilisateur aurait dû retrouver la fiche lui-même...).
Et je sais que ce serait bien de tout faire en React , sûrement plus simple, mais il fallait bien dans mon exercice , que je fasse un CRUD avec Symfony.
Donc je reviens bien sur la fiche de l'animal et mes requêtes de CarList et Form sont stoppées:
Uncaught (in promise) DOMException: The operation was aborted.
Mais si je regarde les requêtes ajax dans la barre de debugg Symfony:
ça ne s'arrête pas ! je ne comprends même pas pourquoi, car je pensait les avoir stoppées...
Et c'est justement la cas où je dois authentifier l'utilisateur... alors où se situe le problème , Symfony ? React ? les deux ?








Répondre avec citation
Partager