Exercices

LocalStorage Weather Api ToDo et LocalStorage

React+ionic

Ionic Create project 4.React Outils utiles 5.Lifecycle Methods 6.JSX

Gestion Ventes

Produit CRUD

6.Form :Ajouter un produit 8.Liste produits 9.Pagination 10.Liste produits +Pagination 11.Liste produits +Datatable 11.Liste produits +load more 12.Supprimer un produit 14.Details d'un produit 15.Recherche et Autocomplete

Reacts:Utils

Gestion des erreurs Variables d'environment Cookies Internationalization proptypes Form validation React Animation Fragment Google Maps

Utilisateur CRUD

18.Inscription upload file 19.Connexion et Les sessions 19.Connexion: JWT Token

Ventes CRUD

17.Vendre un produit 18.Facture Generate PDF 19.Statisques Charts

Redux





React:Hooks

folder Projet: test_react_project
Hooks est une APIs react qui contient un ensemble de fonctions qui permet de gérer le State du component et les lifeCyle méthodes il existe plusieurs fonctions Hook:
  1. 1useState :permet de gérer le State d'une component
  2. 2useEffect S'éxcute lorsque:
    1.une fois le component est lancé
    2.à chaque changement d'une variable de state
    Exemple
    import { useEffect, useState } from "react";

    export default function ExampleUseEffect()
    {
        const [nombre,setNombre]=useState()
        const [variable1,SetVariable1]=useState('')
        const [client,setClient]=useState({
           nom:'',
           prenom:''
        })
       
        useEffect(()=>{
    /*
    le code de useffect s'éxécute automatiquement à chaque chagement
    d'une variable de state
    */

     })
    }
    /*Remarque :on peut spécifier la liste des variables de state qui controle useEffect */
    useEffect(()=>{
        //ce code s'éxcute à chaque changement de la variable client ou variable1

    },[client,variable1])


  3. Remarque
    userEffect joue le mêle rôle que les fonctions :
    componentDidMount():s'éxécte automatiquement une fois la component est lancé
    componentDidUpdate():s'éxécute lorsque il y a un chagement de state
    componentWillUnmount() s'éxécute juste avant la fermeture du component
  4. 3useContext:est un mecanise qui permet de partager et propager les données entre les components mères et ses fille
Note Pour utiliser les hook on doit créer les component sous forme de fonction
export default function Details() {
//...
return (
<div>
</div>):
}
1.useState() hooks

1.useState () avec les variables simples

import { useState } from "react"
export default function UseStateExemple1()
{
    const [nom,setNom]=useState("abc")

    return (
   
        <div>
         {nom}
         <input type="button" onClick={()=>setNom("xyz")} value="modifier"/>
         <input type="text" onChange={(event)=>setNom(event.target.value)} />
        </div>
    )
   
}


npx crcf src/components/client
import React, { Component, useState } from 'react';
/*Pour utiliser les hook on doit créer les com*/
export default function Client() {
/*Déclaration de la state avec un deux variable nom et prenom
setNom et setPrenom se sont deux méthodes qui seront utilisée pour modifier la valeur du nom er prenom*/
const [nom, setNom] = useState("Valeur Initiale");
const [prenom, setPrenom] = useState("amal");;

/*Deux fonctions qui ecoute les changments du nom er prenom puis modifier la State*/
const inputChange = (e) => {
/*<input name="nom" est changé*/
if(e.target.name=="nom")
{
setNom(e.target.value);
}
/*<input name="prenom" est changé*/
else if(e.target.name=="prenom")
{
setPrenom(e.target.value);
}
}

return (
<div>
{/*{nom} est la variable de la state :{nom}=>this.state.nom*/}
<h1>Test useState</h1><center>
<table style={{border:"1px solid #000",width:'50%'}}>
<tr>
<td>Nom</td>
<td><input value={nom} onChange={inputChange} name="nom" type="text"/></td>
</tr>
<tr>
<td>Prenom</td>
<td><input value={prenom} onChange={inputChange} name="prenom" type="text"/></td>
</tr>
<tr>
<td colspan="2">
<p style={{background:"#eee"}}>
Afficher la valeur du state :<br/> Nom : <b>{nom}</b><br/> Prenom :<b> {prenom}</b>
</p>
</td>
</tr>
</table></center>
</div>
);
}

App.js

import logo from './logo.svg';
import './App.css';
/*importer la component client*/
import Client from './components/client/client.js'
function App() {
return (
<div className="App">
<Client />
</div>
);
}

export default App;


2.useState() avec un objet

import { useState } from "react"

export default function UseStageExempleObject()
{
    const [post,setPost]=useState({
        id:1,
        titre:'',
        text:''
    })
    /*c'est la meme chose que
    this.state={
        post:{
            id:'',
            titre:'',
            text:''
        }
    }
    */

    const getValue=(event)=>{
       setPost((prevPost=>({
           ...prevPost,
           [event.target.name]:event.target.value
       })))
    }

    return(
        <div>
<table>
    <tr>
        <td>Titre</td>
        <input type="text" name="titre" onChange={getValue}/>
    </tr>
    <tr>
        <td>Text</td>
        <textarea  name="text" onChange={getValue}></textarea>
    </tr>
   
</table>
les informations du post sont :<br/>
id:{post.id}<br/>
Titre: {post.titre}<br/>
Text :{post.text}
</div>
    )
}


Exemple 2
import React, { useState } from 'react';

function Counter() {
  // Utilisation de useState pour déclarer une variable d'état "count" avec une valeur initiale de 0
  const [count, setCount] = useState(0);

  // Fonction pour incrémenter le compteur
  const increment = () => {
    setCount(count + 1);
  };

  // Fonction pour décrémenter le compteur
  const decrement = () => {
    setCount(count - 1);
  };

  return (
    <div>
      <p>Compteur : {count}</p>
      <button onClick={increment}>Incrémenter</button>
      <button onClick={decrement}>Décrémenter</button>
</div>
  );
}

export default Counter;
Exemple 3
import React, { useState } from 'react';

function FormExample() {
  // Utilisation de useState pour déclarer une variable d'état "inputValue" avec une valeur initiale vide
  const [inputValue, setInputValue] = useState('');

  // Fonction pour gérer les changements de saisie dans le champ de formulaire
  const handleInputChange = (event) => {
    setInputValue(event.target.value);
  };

  return (
    <div>
      <h2>Formulaire avec useState</h2>
      <input
        type="text"
        placeholder="Saisissez quelque chose..."
        value={inputValue}
        onChange={handleInputChange}
      />
      <p>Vous avez saisi : {inputValue}</p>
    </div>
  );
}

export default FormExample;
npx crcf src/components/clientObject
import React, { Component, useState } from 'react';
export default function ClientObject() {
/*Création d'une State avec l'objet Client */
const [client, setClient] = useState({ nom: "", prenom: "" });
const inputChange = e => {
/*Récupérer l'input changé*/
const { name, value } = e.target;
/*Modifier dans le state l'attirbut Client changé*/
setClient(prevClient => ({
...prevClient,/*Récupérer l'ancien objet*/
[name]: value /*changé la valeur de l'attribut :<input name="nom" ou name="prenom"*/
}));
};

return (
<div>
{/*{client.nom} est la variable de la state :{nom}=>this.state.client.nom*/}
<input value={client.nom} onChange={inputChange} name="nom" type="text" /><br />
<input value={client.prenom} onChange={inputChange} name="prenom" type="text" />
<p>
Afficher la valeur du state :
<span style={{background:'#efefef'}}>
<br/>Nom:<b>{client.nom}</b>
<br/> Prenom:<b>{client.prenom}</b>
</span>
</p>
</div>
);
}

App.js

import logo from './logo.svg';
import './App.css';
/*importer la component client*/
import ClientObject from './components/clientObject/clientObject.js'
function App() {
return (
<div className="App">
<ClientObject />
</div>
);
}

export default App;

useState() avec un tableau d'objets

import { useState } from "react"

export default function TpuseStateTableau()
{
    //variable state pour récupérer les données from les inupts
    const [film,setFilm]=useState({
        idfilm:1,
        titre:'',
        duree:0,
        genre:''
    })

    //variable de state de type taleau pour sauvegarder les film ajouté
    const [listeFilms , setListeFilms]=useState([])

    //une fonction qui permet de récupérer les valeurs de inputs
    const getFilm=(event)=>{
        setFilm(prevFilm=>({
            ...prevFilm,
            [event.target.name]:event.target.value
        }))
    }


    const ajouterFilm=()=>{
        if(film.titre!='' && film.genre!='' && film.duree>0)
        {
          setListeFilms((prevListeFilms)=>(
            [...prevListeFilms,film]
          ))
         
          //intialiser l'objet film et incrémenter l'id
          setFilm({
            idfilm:film.idfilm+1,
            titre:'',
            genre:'',
            duree:0
          })
        }

    }


    return(

<div>
    <fieldset>
        <legend>Ajouter un film</legend>
 
    <table>
        <tr>
            <td>Titre</td>
            <td><input type="text" name="titre" onChange={getFilm}  value={film.titre}/></td>
        </tr>
        <tr>
            <td>Duree</td>
            <td><input type="number" name="duree" onChange={getFilm} value={film.duree}/></td>
        </tr>
        <tr>
            <td>genre</td>
            <td><input type="text" name="genre" onChange={getFilm} value={film.genre}/></td>
        </tr>
        <tr>
            <td></td>
            <td><input type="button" value="Ajouter" onClick={ajouterFilm}/></td>
        </tr>
    </table>
    </fieldset>
    <h3>Listes films</h3>
    <table>
        <thead>
        <th>Id</th>
        <th>Titre</th>
        <th>Genre</th>
        <th>Durée</th>
        </thead>
        <tbody>
            {
                listeFilms.map((f)=>{
                    return (
                        <tr>
                            <td>{f.idfilm}</td>
                            <td>{f.titre}</td>
                            <td>{f.genre}</td>
                            <td>{f.duree}</td>
                        </tr>
                    )
                })
            }
        </tbody>
    </table>
</div>

    )
}


Exemple 2
import React, { useState } from 'react';

function TaskList() {
  // Utilisation de useState pour déclarer une variable d'état 
  //"tasks" avec une valeur initiale, un tableau d'objets
  const [tasks, setTasks] = useState([
    { id: 1, text: 'Tâche 1', completed: false },
    { id: 2, text: 'Tâche 2', completed: true },
    { id: 3, text: 'Tâche 3', completed: false }
  ]);

  // Fonction pour marquer une tâche comme complétée
  const completeTask = (taskId) => {
    const updatedTasks = tasks.map((task) => {
      if (task.id === taskId) {
        return { ...task, completed: !task.completed };
      }
      return task;
    });
    setTasks(updatedTasks);
  };

  return (
<div>
      <h2>Liste des tâches</h2>
      <ul>
        {tasks.map((task) => (
          <li key={task.id}>
            <span
              style={{ textDecoration: task.completed ? 'line-through' : 'none' }}
              onClick={() => completeTask(task.id)}
            >
              {task.text}
            </span>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default TaskList;
Exemple 4
import React, { useState } from 'react';

// Composant fonctionnel pour afficher une tâche
function TaskItem({ task, onDelete }) {
  return (
    <li>
      {task}
      <button onClick={onDelete}>Supprimer</button>
    </li>
  );
}
export default TodoListApp;

// Composant parent
function TodoListApp() {
  const [tasks, setTasks] = useState([]);
  const [newTask, setNewTask] = useState('');

  const addTask = () => {
    if (newTask.trim() !== '') {
      setTasks([...tasks, newTask]);
      setNewTask('');
    }
  }

  const deleteTask = (index) => {
    const updatedTasks = [...tasks];
    updatedTasks.splice(index, 1);
    setTasks(updatedTasks);
  }

  return (
    <div>
      <h1>Ma Liste de Tâches</h1>
      <div>
        <input
          type="text"
          value={newTask}
          onChange={(e) => setNewTask(e.target.value)}
          placeholder="Ajouter une tâche"
        />
        <button onClick={addTask}>Ajouter</button>
      </div>
      <ul>
        {tasks.map((task, index) => (
          <TaskItem key={index} task={task} onDelete={() => deleteTask(index)} />
        ))}
      </ul>
    </div>
  );
}

export default TodoListApp;

2.useEffect() hooks

Exemple 1
import React, { useState, useEffect } from 'react';

function ExampleComponent() {
  const [message, setMessage] = useState('');

  // Utilisation de useEffect pour afficher un message lorsque le composant est monté
  useEffect(() => {
    setMessage('Le composant est monté !');
  }, []); // Le tableau vide [] signifie que cette fonction s'exécutera uniquement après le montage initial du composant

  return (
    <div>
      <h2>Exemple d'utilisation de useEffect</h2>
      <p>{message}</p>
    </div>
  );
}

export default ExampleComponent;
Exemple 2

import React, { useState, useEffect } from 'react';

function Timer() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    // Utilisation de useEffect pour incrémenter le compteur de secondes chaque seconde
    const interval = setInterval(() => {
      setSeconds((prevSeconds) => prevSeconds + 1);
    }, 1000);

    // La fonction de nettoyage arrête l'incrémentation lorsque le composant est démonté
    return () => clearInterval(interval);
  }, []); // Le tableau vide [] signifie que cette fonction s'exécutera uniquement après le montage initial du composant

  return (
  <div>
      <h2>Compteur de secondes</h2>
      <p>{seconds} secondes</p>
    </div>
  );
}

export default Timer;
Exemple 3:useEffect avec localStorage
import React, { useState, useEffect } from 'react';

function LocalStorageExample() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    // Utilisation de useEffect pour récupérer la valeur de "count" depuis le localStorage lors du montage du composant
    const storedCount = localStorage.getItem('count');
    if (storedCount) {
      setCount(Number(storedCount));
    }
  }, []); // Le tableau vide [] signifie que cette fonction s'exécutera uniquement après le montage initial du composant

  useEffect(() => {
    // Utilisation de useEffect pour mettre à jour le localStorage à chaque changement de "count"
    localStorage.setItem('count', count.toString());
  }, [count]);

  const increment = () => {
    setCount(count + 1);
  };

  return (
     <div>
      <h2>Exemple d'utilisation de useEffect avec localStorage</h2>
      <p>Count : {count}</p>
      <button onClick={increment}>Incrémenter Count</button>
    </div>
  );
}

export default LocalStorageExample;
Liste de contacts avec filtrage
import React, { useState } from 'react';

function ContactList() {
  const [contacts, setContacts] = useState([]);
  const [newContact, setNewContact] = useState('');
  const [filter, setFilter] = useState('');

  const addContact = () => {
    if (newContact.trim() !== '') {
      setContacts([...contacts, newContact]);
      setNewContact('');
    }
  };

  const deleteContact = (index) => {
    const updatedContacts = [...contacts];
    updatedContacts.splice(index, 1);
    setContacts(updatedContacts);
  };

  return (
    <div>
      <h2>Liste de contacts</h2>
      <div>
        <input
          type="text"
          placeholder="Nouveau contact"
          value={newContact}
          onChange={(e) => setNewContact(e.target.value)}
        />
        <button onClick={addContact}>Ajouter</button>
      </div>
      <div>
        <input
          type="text"
          placeholder="Filtrer par nom"
          value={filter}
          onChange={(e) => setFilter(e.target.value)}
        />
      </div>
      <ul>
        {contacts
          .filter((contact) => contact.includes(filter))
          .map((contact, index) => (
            <li key={index}>
              {contact}
              <button onClick={() => deleteContact(index)}>Supprimer</button>
            </li>
          ))}
      </ul>
    </div>
  );
}

export default ContactList;
Formulaire de création de compte
import React, { useState } from 'react';

function SignupForm() {
  const [username, setUsername] = useState('');
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [isSubmitted, setIsSubmitted] = useState(false);

  const handleSubmit = (e) => {
    e.preventDefault();
    setIsSubmitted(true);
  };

  return (
   <div>
      <h2>Formulaire de création de compte</h2>
      {isSubmitted ? (
        <p>Compte créé !</p>
      ) : (
        <form onSubmit={handleSubmit}>
          <label>
            Nom d'utilisateur:
            <input
              type="text"
              value={username}
              onChange={(e) => setUsername(e.target.value)}
            />
          </label>
          <label>
            Adresse e-mail:
            <input
              type="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
            />
          </label>
          <label>
            Mot de passe:
            <input
              type="password"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
            />
          </label>
          <button type="submit">Créer un compte</button>
        </form>
      )}
    </div>
  );
}

export default SignupForm;

Exemple:Sauvegarder le State dans le localStorage

npx crcf components/TestHooks/clientEffect
import React, { Component, useState, useEffect } from 'react';
export default function ClientEffect() {

/*Création d'une State avec l'objet Client */
const [client, setClient] = useState(
{
/*Initialiser le nom par la valeur stocker dans le LocalStorage ou '' s'il n'existe pas*/
const clientLocalString = localStorage.getItem("Client");
const clientLocalObject= JSON.parse(clientLocal);
nom: clientLocalObject.nom || '',
prenom: clientLocalObject.prenom || ''

});

/*surveiller les changments des inputs*/
const inputChange = e => {
/*Récupérer l'input changé*/
const { name, value } = e.target;
/*Modifier dans le state l'attirbut Client changé*/
setState(prevClient => ({
...prevClient,/*Récupérer l'ancien objet*/
[name]: value /*changé la valeur de l'attribut :<input name="nom" ou name="prenom"*/
}));
};

/*Sauvegarder l'objet client dans le localStorage storage chaque fois qu'il y a un changment
changment=> si les lifeCyle méthodes s'exécute:=>userEffect s'exécute
componentDidMount(), componentDidUpdate(), and componentWillUnmount()
*/
useEffect(() => {
window.localStorage.setItem('Client', JSON.stringify(client));
});

return (
<div>
<input value={client.nom} onChange={inputChange} /><br />
<input value={client.prenom} onChange={inputChange} />
<p>
Client, <span>{client.nom} {client.prenom}</span>
</p>
</div>
);
}

2.useContext() hooks

Créer un contextProvider

Créer le fichier dataContext/MonContext.js permettant de créer un Context de l'application puis sauvegarder des données à partager par les autres component du projet
import React from 'react';

/*Créer un context avec un objet vide {}*/
const MonContext = React.createContext({});

export default function MonContextProvider(props) {
/*Recevoir les données à partager */
let donnees=props.value;

return (
<MonContext.Provider value={donnees}>
{/*Créer un provider afin de partager des données avec ses components children*/}

{props.children}
</MonContext.Provider>
);
}
/*Exporter monContext afin de l'appeler avec le nom useContext()*/
export const useMonContext = () => React.useContext(MonContext);

Utiliser MonContext dans les autres Components

Créer trois components TestContextChild1, TestContextChild2 et TestContextChild3
npx crcf components/TestContextChild1
import React,{useContext} from "react";
/*importer le context MonContext*/
import { useMonContext } from '../../dataContext/MonContext.js';

function TestContextChild1() {
/*Récupérer le context MonContext*/
const donnees = useMonContext();

return (<div className="bg-info">
TestContextChild1<br/>
{/*Utiliser les données du Context*/}
nom:{donnees.nom}<br/>
siteweb:{donnees.siteweb}<br/>
cours:{donnees.cours}<br/>
</div>);
}
export default TestContextChild1;

npx crcf components/TestContextChild2
import React,{useContext} from "react";
/*importer la component TestContextChild3 */
import TestContextChild3 from '../TestContextChild3/TestContextChild3.js';

function TestContextChild2() {
return (<div className="bg-warning">
TestContextChild2<br/>
<div style={{ padding : "20px" , color : "white" }}>
{/*appeler la component TestContextChild3 */}
<TestContextChild3 />
</div>
</div>);
}

export default TestContextChild2;


npx crcf components/TestContextChild3
import React,{useContext} from "react";
import { useMonContext } from '../../dataContext/MonContext.js';


function TestContextChild3() {
/*Récupérer le context MonContext*/
const donnees = useMonContext();

return (<div className="bg-success">
TestContextChild3<br/>
{/*Utiliser les données du Context*/}
nom:{donnees.nom}<br/>
siteweb:{donnees.siteweb}<br/>
cours:{donnees.cours}<br/>
</div>);
}

export default TestContextChild3;

Modifier App.js

/*importer le hook useContext */
import React ,{useContext} from "react";
/*importer les styles boostrap*/
import 'bootstrap/dist/css/bootstrap.min.css';

import TestContextChild1 from './components/TestContextChild1/TestContextChild1.js';
import TestContextChild2 from './components/TestContextChild2/TestContextChild2.js';

/*importer le context Provider*/
import MonContextProvider from './dataContext/MonContext.js';
function App() {
/*Créer des données à partager avec les components child de MonContextProvider*/
let donnees={
nom:"hakiki",
siteweb:"fixwins",
cours:"ReactJS",
};
return (
<div>
{/*passer les données à toutes les components child */}
<MonContextProvider value={donnees}>
<TestContextChild1 />
<TestContextChild2 />
</MonContextProvider>
</div>
);
}
export default App;