React:Router

folder Projet: test_react_project

Router est un mecanisme qui permet de faire le routage et la navigation entre les components et le passage des paramètres dans URL

Installation:

npm install react-router-dom --save

Exemple1

Nav.js

Contenant les liens de navigation vers l'ensembles des components du projet

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

class Navs extends Component {
  render() {
    return <div className="bgblack">
      <table className="nav">
        <tr>
          <td><a href="/listeProduits">Liste Produits</a></td>
          <td><a href="/AjouterProduit">Ajouter Produit</a></td>
          <td><a href="/info/5">Info/5</a></td>
          <td><a href="/info/5/produit1">Info/5/Produit1</a></td>
          <td><a href="/connexion">Connexion</a></td>
          <td><a href="/inscription">inscription</a></td>
        </tr>
      </table>

    </div>;
  }
}

export default Navs;

ListeProduits.js

Une component permetanat d'afficher la liste des produits

import React, { Component } from "react";


class ListeProduits extends Component {
  render() {
    return <div style={{background:'cyan'}}>
     <span style={{color:"#745"}}>Ici la liste des produits</span>

    </div>;
  }
}

export default ListeProduits;


AjouterPrduit.js

Une component permetanat Ajouter un produit

import React, { Component } from "react";


class AjouterProduit extends Component {
  render() {
    return <div style={{background:'yellow'}}>
     <span style={{color:"#000"}}>Ici La component ajouter Produit</span>

    </div>;
  }
}

export default AjouterProduit;


App.js

importer l'ensembles des components

import React from 'react';
import './App.css';
import Footer from './components/footer';
import Navs from './components/nav/nav';
import ListeProduits from './components/listeProduits'
import AjouterProduit from './components/AjouterProduits'
import { Routes, Route } from 'react-router-dom';


class App extends React.Component{
  constructor(props)
  {
   
    super(props)
 
  }

    render()
    {
      return (
        <div>
     <Navs />
<Routes>
  <Route path='/listeProduits' element={<ListeProduits />}/>
  <Route path='/AjouterProduit' element={<AjouterProduit />} />
</Routes>

<Footer />
        </div>
       
        );
       
      }
     
    }
    export default App;

index.js

Ajouter la balise BrowserRouter

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from "react-router-dom";

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
    <App />
</BrowserRouter>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();


Exemple2

A.Router :URL avec des paramètres

Afin de tester ces Généralité sans toucher le projet front_end_project on va travailler sur le projet test_react_project quant créer dansl partie introduction

Installation:

npm install react-router-dom --save

Modifier la component principale App.js

import React from 'react';
/*importer les styles boostrap*/
import 'bootstrap/dist/css/bootstrap.min.css';
/*Importer les outils de routage */
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import Informations from './components/informations/informations';
function App() {
return (

<Router>
<div className="container "><br/>
<h1>TP :Routage</h1>
{/*Mapping entre les routes et les components */}
<Routes>
{/*1.Sans pramètres: Charger une component sans passé des paramètre */}
<Route path="/info/" element={<Informations/>}/>
{/*2.Avec des paramètres :mapping entre la route /info/15 et la component Informations */}
<Route exact path="/info/:id" element={<Informations/>}/>
{/*3.Avec plusieurs paramètres :mapping entre la route /info/15/Téléphone et la component Informations */}
<Route exact path="/info/:id/:nom" element={<Informations/>}/>
{/*4.On peut Regrouper toutes ces routes dans la meme route en utilisant le symbole ? */}
<Route exact path="/info/:id?/:nom?" element={<Informations/>}/>
{
/*
/info/:id?/:nom? permet de mapper les routes suivantes:
-/info
-info/id
-info/id/nom
*/
}
</Routes>


{/*Création des liens de navigations */}
<br/>Les liens:
<ul className="list-group">
<li className="list-group-item"><a href="/info"className="btn btn-success">Info :Sans Paramètres</a></li>
<li className="list-group-item"><a href="/info/15" className="btn btn-info">Info 15: Avec 1 Paramètre</a></li>
<li className="list-group-item"><a href="/info/15/Name" className="btn btn-danger">Info 15/Name: Avec plusieurs Paramètres</a></li>
</ul>
</div>
</Router>
);
}
export default App;
npx crcf components/informations

Component : informations.js

import React from 'react';
/*useParams :est un hooks une fonction qui permet
d'extraires les les paramètres à partir du URL */
import { useParams } from 'react-router-dom';
/*Règles :pour utiliser les fonctions Hooks :
Il faut définir les Component sous forme des fonctions
*/
function Informations(props) {
/*Extraire l'id from URL : informations/15 */
const { id } = useParams();
/*Extraire le nom from URL : informations/15/Telephone */
const { nom } = useParams();

return (
<div className="border">
<h1>Component:Informations</h1>
<div><b>id= </b>{id}</div>
<div><b>nom= </b>{nom}</div>
</div>
)
}
export default Informations;

B.Router :useNavigate,useLocation,useSearchParams hooks

useNavigate() :Est un hook qui permet de gérer le history de navigation dans l'application et aussi naviguer vers une componenet directement à partir du code javascript en utilisant les fonctions navigate()
useNavigate() : contient plusieurs fonctions:

  1. navigate():permet de naviguer vers une route en passant des données à la component
    supprimer une balise:
  2. navigate(-1): revenir à la dernière route
    navigate(1): aller à la route suivante dans le navigate
  3. Length:sauvgarder le numero d'ordre (index) d'un lien dans le navigate de navigation chaque lien est reconnu par son index (nombre d'ordre)
  4. replace:Fait la même chose que navigate Mais elle va supprimer l'ancien navigate et créer un nouveau navigate

Connexion.js

npx crcf components/Connexion
import React, { useState } from "react"
import { useNavigate } from "react-router-dom"
export default function Connexion()
{
 
    const navigate=useNavigate();
    const [login,setLogin]=useState({email:'',password:''})

    const getValue=(e)=>{
        setLogin(prevlogin=>({
            ...prevlogin,
            [e.target.name]:e.target.value

        }))
    }
    const connexion=(e)=>{
        if(login.email=='abc@email' && login.password=='123')
        {
            navigate("/AjouterProduit",{state:{data:login}})
        }
        else
        {
            navigate({
                pathname:"/inscription",
                search:'?error=Login incorrecte&ok=false'
            })
        }
   
    }
    return(<div>
        <fieldset>
            <legend>Connexion</legend>
            <table>
                <tr>
                    <td>Login</td>
                    <td><input type="email" name="email" onChange={getValue}/></td>
                </tr>
                <tr>
                    <td>Password</td>
                    <td><input type="text" name="password" onChange={getValue}/></td>
                </tr>

                <tr>
                    <td></td>
                    <td><input type="button" onClick={connexion} value="Valider"/></td>
                </tr>
            </table>
        </fieldset>
    </div>)
}

Inscription.js

npx crcf components/Inscription
import React from "react"
import { useSearchParams } from "react-router-dom"
export default function Inscription()
{
    //récupérer les paramètre envoyé via search: dans navigate
    const [searchParams]=useSearchParams();
    const monError=searchParams.get("error")
    const ok=searchParams.get("ok")
   
    return (<div>Inscription:{monError}<br/>
    {ok}</div>)
}

AjouterProduit.js

npx crcf components/AjouterProduit
import React, { Component } from "react";
import { useLocation } from "react-router-dom";
export default function AjouterProduit() {
  //useLocation :permet de récupérer les données envoyées  par navigate dans l'objet state
  const location=useLocation();
  return (
    <div style={{background:'yellow'}}>
      <h1>{JSON.stringify(location.state.data)}</h1>
     <span style={{color:"#000"}}>Ici La component ajouter Produit</span>

    </div>
  )
}


App.js

import React from 'react';
import './App.css';
import {useNavigate,Route,Routes} from 'react-router-dom'
import AjouterProduit from './components/AjouterProduits'
import Connexion from './components/connexion';
import Inscription from './components/Inscription';

function App(props){

 const  navigate=useNavigate();

      return (
        <div>
         <table className="nav">
         
        <tr>
         
          <td><button onClick={()=>{navigate(-1)}}>&lt;</button></td>
          <td><button onClick={()=>{navigate(1)}}>&gt;</button></td>
       
          <td><a href="/connexion">Connexion</a></td>
          <td><a href="/inscription">inscription</a></td>
          <td><a href="/AjouterProduit">inscription</a></td>

        </tr>
      </table>
      <Routes>
 
  <Route path='/AjouterProduit' element={<AjouterProduit />} />
  <Route path='/connexion' element={<Connexion />} />
  <Route path='/inscription' element={<Inscription />} />
</Routes>
    </div>
       
      )
             
    }
    export default App;

Exemple2

Créer une Component de test:
npx crcf components/TestUseHistory
Modifier le type du component de Class vers funtion afin d'utiliser les les fonctions du hooks Api
import React from 'react';
import { BrowserRouter as Router, Routes, Route, Link} from "react-router-dom";
import { useNavigate,useLocation,useSearchParams } from "react-router-dom";

function TestUseHistory() {
/*Instancier un objet useNavigate()*/
const navigate = useNavigate();

/*Créer une fonction qui permet de naviguer vers une route passée en paramètre*/
function NaviguerVers(lien) {
/*navigate :fonction qui prend on paramètre une route*/
navigate(lien);
}
/*Créer une fonction qui permet de naviguer vers une route passée en paramètre*/
function NaviguerWithDonnees(lien,donnees) {
navigate(lien,{state:{nom:'Hakiki',donnees:donnees}});
}

/*Envoyer des paramètres avec search*/
function NaviguerWithParametre(lien,param) {
navigate({
pathname: lien,
search: param,
});
}

function replace(lien) {
navigate(lien, { replace: true })
}

/*Naviguer vers la dernière route*/
function avant() {
navigate(-1);
}

/*Naviguer vers la route suivante du navigate*/
function suivant() {
navigate(1)
}

return (

<div>
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<div className="container-fluid">
<div className="collapse navbar-collapse">
<div className="navbar-nav">
<a className="nav-link" href="/">Component0</a>
<a className="nav-link" href="/route1">Component1</a>
<a className="nav-link" href="/route2">Component2</a>
<a className="nav-link" href="/route3">Component3</a>
</div>
</div>
</div>
</nav>

{/*Créer le mapping entre les routes et les components */}
<Routes>
<Route path="/" element={<Component0 />} />
<Route path="/route1" element={<Component1 />} />
<Route path="/route2" element={<Component2 />} />
<Route path="/route3" element={<Component3 />} />
</Routes>
<br/>

{/*Appler les fonctions crées */}
<h1>Tester les fonctions de useNavigate()</h1>
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<div className="container-fluid">
<div className="collapse navbar-collapse">
<div className="navbar-nav">
<button className="nav-link" onClick={() => NaviguerVers('/route3')}>NaviguerVers</button>
<button className="nav-link" onClick={() => NaviguerWithDonnees('/route2','donnnees Envoyée')}>NaviguerWithDonnees</button>
<button className="nav-link" onClick={() => NaviguerWithParametre('/route2','?parametre=hello&param2=test')}>NaviguerWithParamètre</button>
<button className="nav-link" onClick={() => replace('/route1')}>replace</button>
<button className="nav-link" onClick={avant}>avant</button>

</div>
</div>
</div>
</nav>

</div>

);
}


{/*Créer les Components :Component0,Component1,Component2 et Component3
On peut créer ces components dans des fichier séparés puis les importer
Ou Juste pour tester je vais les créer dans le même fichier (TestUseHistory.js)
*/}
const Component0 = () => <div className="card">
<div className="card-header">
Component0
</div>
<div className="card-body">
Le Contenu ICi du Component0
</div>
</div>;


const Component1 = () => <div className="card">
<div className="card-header">
Component1
</div>
<div className="card-body">
Le Contenu ICi du Component1
</div>
</div>;


const Component2 = (props) => {
/*userLocation() permet de retourner un objet contenant :
{pathname: '/route2', search: '', hash: '', state: {nom: 'Hakiki', donnees: 'donnnees Envoyée'}, key: 'h5tjlqsd'}
envoyés par useNavigate()
*/
let nom='';
let donnees='';
const location = useLocation();
console.log(location);
//Récupérer les données envoyée
if(location.state!=null)
{
nom=location.state.nom;
donnees=location.state.donnees;
}

/* Récupérer les paramètres envoyés dans URL
{pathname: '/route2', search: '?parametre=hello', hash: '', state: null, key: 'hjuj1w94'}
*/
let params='';
if(location.search!=null)
{
params=location.search;
}
console.log(params);


/*On peut récupérer les paramètres envoyés dans URL par useSearchParams Aussi*/
const [searchParams] = useSearchParams();
console.log(searchParams.get('parametre'));

/*Si on a plusieurs paramètres */
for (const entry of searchParams.entries()) {
console.log(entry);
/*entry:['parametre', 'hello']*/
let parametreName=entry[0];
let parametreValue=entry[1];
}

return (
<div className="card">
<div className="card-header">
Component2 :données reçus:{nom} et {donnees}
</div>
<div className="card-body">
Le Contenu ICi du Component2
</div>
</div>)
};



const Component3 = () => <div className="card">
<div className="card-header">
Component3
</div>
<div className="card-body">
Le Contenu ICi du Component3
</div>
</div>;


export default TestUseHistory;

App.js

import React from 'react';
/*importer les styles boostrap*/
import 'bootstrap/dist/css/bootstrap.min.css';

import TestUseHistory from './components/TestUseHistory/TestUseHistory';
import { BrowserRouter as Router } from 'react-router-dom';
function App() {
return (
<div>
{/* la component TestUseHistory est applée à l'intérieur de Router car elle utilise le hook useNavigate() */}
<Router>
<TestUseHistory />
</Router>
</div>
);
}
export default App;