Exercices:Redux
Créer une application avec React et Redux permettant de gérer les posts ,les likes, les comments et les amis
voir figure 1
voir figure 1
Figure1
src/SocialApp/Redux/PostActions.js
export const addPost=(post)=>(
{
type:'Add_Post',
payload:post
});
export const likePost=(idpost)=>({
type:"like_post",
payload:idpost
})
export const dislike=(idpost)=>({
type:"dislike_post",
payload:idpost
})
export const addComment=(idpost,comment)=>({
type:"add_comment",
payload:{idpost,comment}
})
export const deletePost=(idpost)=>({
type:"deletepost",
payload:idpost
})
export const deleteComment=(idpost,idcomment)=>({
type:"supprimer_Comment",
payload:{idpost,idcomment}
})
src/SocialApp/Redux/PostReducer.js
const initialState = {
posts: [{
id:'1',
texte:'post texte1',
likes:0,
comments:[{id:'1',texte:'comment 1'}]
},
{
id:'2',
texte:'post texte2',
likes:0,
comments:[{id:'1',texte:'comment 1 post2'}]
}],
};
const PostReducer = (state = initialState, action) => {
switch (action.type) {
case 'Add_Post':
return { ...state, posts: [...state.posts, action.payload] };
case 'like_post':
return {
...state,
posts:state.posts.map((p)=>{
if(p.id==action.payload){p.likes++}
return p;
})
}
case 'dislike_post':
return {
...state,
posts:state.posts.map((p)=>{
if(p.id==action.payload){p.likes--}
return p;
})
}
case 'add_comment':
return {
...state,
posts:state.posts.map((p)=>{
if(p.id==action.payload.idpost){
p.comments.push(action.payload.comment)
}
return p;
})
}
case 'deletepost':
return {
...state,
posts:state.posts.filter((p)=>p.id!=action.payload)
}
case 'supprimer_Comment':
return {
...state,
posts:state.posts.map((p)=>{
if(p.id==action.payload.idpost)
{
p.comments=p.comments.filter((com)=>com.id!=action.payload.idcomment)
}
return p; })
}
default:
return state;
}
};
export default PostReducer;
src/SocialApp/Redux/store.js
import PostReducer from "./PostReducer";
import { createStore, combineReducers } from 'redux';
const rootReducer = combineReducers({
postReducer: PostReducer,
});
// Créez le store avec les réducteurs combinés
const store = createStore(rootReducer);
export default store;
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import store from './SocialApp/Redux/sotre'
import { Provider } from 'react-redux';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<React.StrictMode>
<App />
</React.StrictMode>
</Provider>
);
src/SocialApp/Components/ListePosts.js
import React, { useEffect, useState } from "react";
import { useDispatch ,useSelector } from "react-redux";
import { addComment, deleteComment, deletePost, dislike, likePost } from "../Redux/PostActions";
import "./listePosts.css"; // Import the CSS file
export default function AfficherListePosts()
{
let listePosts=useSelector(state=>state.postReducer.posts)
const [comment,setComment]=useState({"texte":'',"id":0})
const Dispatch=useDispatch ();
const AddComment=(idpost)=>{
if(comment.texte!="")
{
setComment({...comment,
id:Date.now()})
Dispatch(addComment(idpost,comment))
}
}
const disLike=(idpost)=>{
Dispatch(dislike(idpost))
}
const like=(idpost)=>{
Dispatch(likePost(idpost))
}
const supprimerPost=(idpost)=>{
Dispatch(deletePost(idpost))
}
const supprimerComment=(idpost,idcomment)=>
{
Dispatch(deleteComment(idpost,idcomment))
}
return(<div>
<ul>
{listePosts.map((post)=>{
return (<li style={{"background":"#efefef","margin":"10px"}}>
<div style={{"background":"#000","color":"#fff","padding":"5px"}}>
<span style={{"width":"88%","float":"left"}}>
{post.texte}
</span>
<input type="button" onClick={()=>supprimerPost(post.id)} value="X" style={{"background":"red","font-size":"8px"}}/>
<input type="button" value="Edit" style={{"background":"green","font-size":"8px"}}/>
<br/>
<input type="button" onClick={()=>like(post.id)} value={"Like " +post.likes}/>
<input type="button" onClick={()=>disLike(post.id)} value="Dislike"/>
</div>
Listes Comments:<br/>
<ol style={{"background":"yellow"}}>
{post.comments.map((com)=>{
return (<li>
<span style={{"width":"93%","float":"left"}}>
{com.texte}
</span>
<input type="button" onClick={()=>supprimerComment(post.id,com.id)} value="X" style={{"background":"red","font-size":"8px"}}/>
</li>)
})}
</ol>
<input type="text"name="texte" onChange={(event)=>setComment({...comment,"texte":event.target.value})} />
<input type="button" onClick={()=>AddComment(post.id)} value="Add Comment"/>
</li>)
})}
</ul>
</div>)
}
src/SocialApp/Components/AjouterPosts.js
import React, { useState } from "react";
import { useDispatch } from "react-redux";
import { addPost } from "../Redux/PostActions";
export default function AjouterPost()
{
const [post,setPost]=useState({
id:Date.now(),
texte:'',
likes:0,
comments:[]
})
const [message ,setMessage]=useState("");
const Dispatch=useDispatch();
const ajouterPost=()=>{
if(post.texte!="")
{
Dispatch(addPost(post))
setMessage("Bien ajouté")
setPost({...post,texte:"",id:Date.now()})
}
else
{
setMessage("Le texte est obligatoires")
}
}
return (<div>
<textarea name="texte" onChange={(event)=>setPost({...post,texte:event.target.value})}>What's in your mind</textarea>
<br/> <input type="button" value="Ajouter" onClick={ajouterPost} />
{message}
</div>)
}
App.js
import React from "react";
import { BrowserRouter,Routes,Route,Link } from "react-router-dom";
import "./App.css"
import AfficherListePosts from "./SocialApp/Components/ListePosts";
import AjouterPost from "./SocialApp/Components/AjouterPosts";
import { useSelector } from "react-redux";
export default function App()
{
const listePosts=useSelector((state)=>state.postReducer.posts)
return (<div>
<BrowserRouter>
<Link to="/listePosts">Posts : <input type="button" value={listePosts.length} style={{"background":"blue","font-size":"12px","padding":"2px"}}/>
</Link>
<Link to="/ajouterPost">Ajouter post
</Link>
<Link to="/ajouterAmi">Amis : <input type="button" value="5" style={{"background":"blue","font-size":"12px","padding":"2px"}}/>
</Link>
<Routes>
<Route path="/listePosts" element={<AfficherListePosts/>}/>
<Route path="/ajouterPost" element={<AjouterPost/>}/>
</Routes>
</BrowserRouter>
</div>)
}
src/SocialApp/Components/listePosts.css
/* Basic styling for the container */
div {
max-width: 800px;
margin: 5px auto;
}
/* Styling for the list of posts */
ul {
list-style-type: none;
padding: 0;
}
/* Styling for each individual post */
li {
background: #efefef;
margin: 5px;
padding: 5px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
/* Styling for the like/dislike buttons */
input[type="button"] {
margin: 5px;
padding: 8px 12px;
width:auto;
cursor: pointer;
border: none;
border-radius: 4px;
background-color: #3498db;
color: #fff;
}
/* Styling for the comments list */
ol {
background: #fff;
padding: 10px;
margin-top: 20px;
}
/* Styling for each individual comment */
ol li {
margin-bottom: 10px;
}
/* Responsive design for smaller screens */
@media (max-width: 600px) {
li {
padding: 15px;
}
}