Crud :Exemple

Créer une application Crud permet d'exécuter les méthodes (HTTP POST, GET, PUT, and DELETE)
Afin d'exécuter les Requests http on a besoin d'un serveur backEnd on peut créer un serveur de test à l'aide de json-server
npm install -g json-server
npm install json-server
json-server --watch db.json --port 3004
Le fichier db.json est Créer contenant:

Remarque: Si vous avez une erreur veuillez lancer la commande suivante:

Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process
json-server --watch db.json --port 3004
Installer Axios
le module Axios de React pour consommer les Rest Apis crées dans nodeJs project
npm install axios --save
{
"posts": [
{
"id": 1,
"title": "json-server",
"author": "typicode"
}
],
"comments": [
{
"id": 1,
"body": "some comment",
"postId": 1
}
],
"profile": {
"name": "typicode"
}
}
Le serveur backEnd est lancer sur :
Resources
http://localhost:3004/posts
http://localhost:3004/comments
http://localhost:3004/profile

Tester l'api

On peut executer les requests http sur l'api comme:
Get :http://localhost:3004/posts =>Afficher la liste des posts
Get:http://localhost:3004/posts/1 =>Afficher les détails d'un post passé en pramètre
Post:http://localhost:3004/posts =>Ajouter un nouveau post
Delete:http://localhost:3004/posts/1=>Suprimer un post
Put:http://localhost:3004/posts/1=>Modifier un post
GET:http://localhost:3004/posts
POST:http://localhost:3004/posts

1.Créer des components

Afin de gérer les posts ,ajouter,afficher,modifier,supprimer on doit créer les components correpondants:
npx crcf components/Crud/listePost
import React, { Component, useEffect, useState } from "react";
import axios from "axios";
import './listePosts.css';
export default function ListPosts(){
const [listeposts,setListeposts]=useState([{}])
    useEffect(()=>{
axios.get("http://localhost:3004/posts").then((res)=>{
    setListeposts(res.data)
    console.log(listeposts)
})
    },[]);

    return (<div>

        <table className="table">
            <thead>
            <th>ID</th>
            <th>Title</th>
            <th>Author</th>
            </thead>
            <tbody>
                {listeposts.map((post)=>{
                    return (
                        <tr>
                            <td>{post.id}</td>
                            <td>{post.title}</td>
                            <td>{post.author}</td>
                        </tr>
                    )
                })}
            </tbody>
        </table>
       

    </div>)
}
App.js
import React from 'react';
import './App.css';
import {useNavigate,Route,Routes} from 'react-router-dom'
import ListPosts from './components/Crud/listePost';


function App(props){


      return (
        <div>
          <table className='table'>
            <tr>
              <td><a href="/posts">Listes Post</a></td>
              <td><a href="/posts/add">Ajouter nouveau posts</a></td>
              <td><a href="/comments">Liste Commentaires</a></td>
              <td><a href="/comments/add">Ajouter un nouveau commentaire</a></td>
            </tr>
          </table>
          <Routes>
            <Route path='/posts' element={<ListPosts />} />
          </Routes>
       
    </div>
       
      )
       
       
    }
    export default App;

npx crcf components/Crud/addPost
import axios from "axios";
import React, { Component, useState } from "react";
 import './addPost.css'
function AddPost() {
  //créer une variable de state contenant un post
  const [post,setPost]=useState({"id":0,"title":'',"author":''})
  const [message,setMessage]=useState();
  const [errerstyle,setErreurstyle]=useState({"background":"#000","color":"#fff"})
 
  //récupérer les valeurs du input puis les enregistrées dans
  //la variable du state post
  const getValue=(e)=>{
    setPost(prevPost=>({
      ...prevPost,
      [e.target.name]:e.target.value
    }))
  }

  //envoyer les données aux serveurs backend
  const add=()=>{
//vérifier si tout les champs sont remplis
if(post.id!='' && post.title!='' && post.author!='')
{

  axios.post("http://localhost:3004/posts",post).then((res)=>{
   
   if(res.status==201)
   {
    setMessage("bien ajouter")
    setErreurstyle({"background":"#000","color":"#fff"})

   }
   else
   {
    setMessage("Erreur du BackEnd")
    setErreurstyle({"background":"red","color":"#fff"})
   }
})
}
else
{
  setMessage('Erreur tout les champs sont obligatoires')
  setErreurstyle({"background":"red","color":"#fff"})

}

  }
    return(

     <div><fieldset>
      <legend>Add new Post</legend>
      <table className="table">
        <tr>
          <td>Id</td>
          <td><input type="number" name="id"  onChange={getValue} /></td>
        </tr>
        <tr>
          <td>Title</td>
          <td><input type="text"  name="title" onChange={getValue} /></td>
        </tr>
        <tr>
          <td>Author</td>
          <td><input type="text"  name="author"  onChange={getValue}/></td>
        </tr>
        <tr>
          <td></td>
          <td><input type="button" onClick={add} value="Save" /></td>
        </tr>
      </table>
     <span style={errerstyle}> {message}</span>
      </fieldset></div>
     
     );
 
}

export default AddPost;

App.js
import React from 'react';
import './App.css';
import {useNavigate,Route,Routes} from 'react-router-dom'
import ListPosts from './components/Crud/listePost';
import AddPost from './components/Crud/addPost/addPost';


function App(props){

 

      return (
        <div>
          <table className='table'>
            <tr>
              <td><a href="/posts">Listes Post</a></td>
              <td><a href="/posts/add">Ajouter nouveau posts</a></td>
              <td><a href="/comments">Liste Commentaires</a></td>
              <td><a href="/comments/add">Ajouter un nouveau commentaire</a></td>
            </tr>
          </table>
          <Routes>
            <Route path='/posts' element={<ListPosts />} />
            <Route path='/posts/add' element={<AddPost />} />
           
          </Routes>
       
    </div>
       
      )
       
     
     
    }
    export default App;

Supprimer Post

Modifier la components listPost

ListPosts.js

import React, { Component, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import axios from "axios";
import './listePosts.css';
export default function ListPosts(){
    const navigate=useNavigate();
const [listeposts,setListeposts]=useState([{}])
const [errorsupprimer,setErrorsupprimer]=useState("")
    useEffect(()=>{
axios.get("http://localhost:3004/posts").then((res)=>{
    setListeposts(res.data)
})
    },[]);

    const supprimer=(id)=>{
        //supprimer le post from backend
        axios.delete("http://localhost:3004/posts/"+id).then((res)=>{
            if(res.status==200)
            {
                //supprimer le post from listpots
                const listReste=listeposts.filter(item=>(item.id!=id))
                setListeposts(listReste)

               
            }
            else
            {
                setErrorsupprimer("<span style='color:red'>Erreur de suppression</span>");
            }

        })
    }

    //naviguer vers la components Modifier en envoyant le post à modifié
    // dans  {state:{post:post}}
    const modifier=(post)=>{
        navigate("/posts/modifier/",{state:{post:post}})
    }
    return (<div>

        <table className="table">
            <thead>
            <th>ID</th>
            <th>Title</th>
            <th>Author</th>
            </thead>
            <tbody>
                {listeposts.map((post)=>{
                    return (
                        <tr>
                            <td>{post.id}</td>
                            <td>{post.title}</td>
                            <td>{post.author}</td>
                            <td>
                                <button onClick={()=>{supprimer(post.id)}}>Supprimer</button>
                                <button onClick={()=>{modifier(post)}}>Modifier</button>
                                </td>
                        </tr>
                    )
                })}
            </tbody>
        </table>
        {errorsupprimer}

    </div>)
}

Modifier un Post

Modifier la components App.js en ajoutant la route pour modifier

App.js

import React from 'react';
import './App.css';
import {useNavigate,Route,Routes} from 'react-router-dom'
import ListPosts from './components/Crud/listePost';
import AddPost from './components/Crud/addPost/addPost';
import ModifierPost from './components/Crud/ModifierPost/ModifierPost';

function App(props){

      return (
        <div>
          <table className='table'>
            <tr>
              <td><a href="/posts">Listes Post</a></td>
              <td><a href="/posts/add">Ajouter nouveau posts</a></td>
              <td><a href="/comments">Liste Commentaires</a></td>
              <td><a href="/comments/add">Ajouter un nouveau commentaire</a></td>
            </tr>
          </table>
          <Routes>
            <Route path='/posts' element={<ListPosts />} />
            <Route path='/posts/add' element={<AddPost />} />
            <Route path='/posts/modifier' element={<ModifierPost />} />
          </Routes>
       
    </div>
       
      )
 
    }
    export default App;

Créer la component ModifierPost permettant de modifier un post 

ModifierPost.js

import axios from "axios";
import React, { Component, useState } from "react";
import {useLocation,useNavigate} from 'react-router-dom'

export default function ModifierPost() {
  //récupérer les données envoyées par :navigate("/posts/modifier/",{state:{post:post}})
  const location=useLocation()
  //une variable de state permettant de sauvgarder le post à modifié
  const [post,setPost]=useState(location.state.post);
 
  const navigate=useNavigate();
  //récupérer les input changé et les sauvegarder dans la variable post du state
  const getValue=(e)=>{
    setPost(prevPost=>({
      ...prevPost,
      [e.target.name]:e.target.value
    }))
  }

  const valider=()=>{
    //vérifier si tout les champs sont remplis
    if(post.id!="" && post.title!="" && post.author!="")
    {
   axios.put("http://localhost:3004/posts/"+post.id,post).then((res)=>{
    if(res.status==200)
    {
   navigate("/posts")
    }
   })
    }
    else
    {
      alert("Erreur :tout les champs sont obligatoires")
    }
  }

    return (<div>
       <div><fieldset>
      <legend>Add new Post</legend>
      <table className="table">
        <tr>
          <td>Id</td>
          <td><input type="number" name="id" defaultValue={post.id}   disabled/></td>
        </tr>
        <tr>
          <td>Title</td>
          <td><input type="text"  name="title" onChange={getValue} defaultValue={post.title} /></td>
        </tr>
        <tr>
          <td>Author</td>
          <td><input type="text"  name="author" onChange={getValue} defaultValue={post.author} /></td>
        </tr>
        <tr>
          <td></td>
          <td><input type="button"  value="Valider" onClick={valider} /></td>
        </tr>
      </table>
      </fieldset></div>
    </div>)
  }