J'ai des pages React (BlogContent & RelatedBlog),
"BlogContent": Pour afficher le contenu de l'article pour l'auteur et en bas de la page se trouvent ses autres articles. "RelatedBlog": Affiche l'autre article appartenant au même auteur que l'utilisateur souhaite lire
Lorsqu'un utilisateur consulte le contenu d'un blog, il peut voir ci-dessous plus de blogs pour l'auteur. Lorsque l'utilisateur clique sur l'article qu'il souhaite lire, le slug sur Url change mais le contenu ne change pas tant que l'utilisateur n'a pas actualisé la page. L'utilisateur doit donc actualiser la page chaque fois qu'il souhaite voir tous les blogs liés à l'auteur.
Je pense que la raison pour laquelle la page de blog nécessite des actualisations à chaque fois est due à useEffect(), mais je ne sais pas quelle est l'astuce pour y remédier
Voici mon code pour la page BlogContent :
import React, { useEffect, useState } from 'react';
import { useParams } from "react-router-dom";
import { ClockCircleOutlined } from '@ant-design/icons';
import { Image, Layout, Typography } from 'antd';
import axiosInstance from '../../axios';
import { RelatedBlog } from './RelatedBlog';
export const BlogContent = () => {
const { slug } = useParams(); //to show blog based on slug
const [data, setData] = useState({ posts: [] });
useEffect(() => {
axiosInstance.get(slug).then((res) => {
setData({ posts: res.data });
});
}, [setData]);
const { Content } = Layout;
const { Title, Paragraph, Text } = Typography;
let AuthorBlog = data.posts.author // Extract the author name and pass them all as prop
return (
<>
<Layout>
<Content>
<Image src={data.posts.image} preview={false}/>
<Layout>
<Typography>
<Title level={2}>{data.posts.title}</Title>
<Text>Created By: <Text strong className='writer' {data.posts.author}</Text></Text>
<div className='dateDiv'><ClockCircleOutlined style={{
color: 'rgb(59, 110, 145)',
fontSize: '1.2rem', paddingRight: '0.6rem'}} />
<Text className='date'>Published on:{' '} {new Date(data.posts.published).toDateString()}</Text></div>
</Typography>
</Layout>
<Layout>
<Typography>
<Paragraph>{data.posts.content}</Paragraph>
</Typography>
</Layout>
</Content>
</Layout>
<RelatedBlog AuthorBlog={AuthorBlog}/> // put author as prop to render all blogs for athor
</>
);
};
et ici pour RelatedBlog : ce bouton permet à l'utilisateur d'accéder à un autre article<Lien vers={ /post/${blog.slug}
}>Continuer la lecture
import React, { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import axiosInstance from '../../axios';
export const RelatedBlog = (props) => {
const { AuthorBlog } = props;
const [appState, setAppState] = useState([]);
useEffect(() => {
axiosInstance.get("/").then((res) => {
const allBlogs = res.data;
setAppState(allBlogs);
});
}, [setAppState]);
// Fetch all blogs and filter to just display blogs' author
const filterAuthor = appState.filter((item) => item.author === AuthorBlog);
console.log("The Author", filterAuthor);
return (
<section className='container'>
<div>
<h2 className="pt-5">more related</h2>
</div>
<p style={{marginLeft:'22px',marginTop:'35px', fontWeight:'bold', fontSize:'20px'}}><strong>Total blogs: </strong>{filterAuthor.length}</p>
<div className='row'>
{filterAuthor.map((blog) => (
<div key={blog.id} className="m-2 text-center col-lg-3 col-md-3">
<div className='card'>
<div className="card-body">
<h5>{blog.title.substr(0, 35)}...</h5>
<p>{blog.content.substr(0, 150)}...</p>
// here user click on botton to go to other article
<Link to={`/post/${blog.slug}`} style={{color:'rgb(59, 110, 145)', fontSize:'1rem'}}>Continue reading...</Link>
</div>
</div>
</div>
))}
</div>
</section>
)}
App.js :
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import './App.css';
import { Navbar } from './components/Navbar';
import Home from './components/pages/Home';
import {BooksCard} from './components/pages/Card/BooksCard';
import {Footer} from './components/Footer';
import {ContactPage} from './components/pages/ContactPage';
import { Articles } from './components/pages/ArticlePage/Articles';
import Admin from './components/pages/Dashboard/Admin';
import {Create} from './components/pages/Dashboard/Create';
import {Edit} from './components/pages/Dashboard/Edit';
import {Delete} from './components/pages/Dashboard/Delete';
import { Profile } from './components/pages/Profile';
import {Error} from './Error';
import { BlogContent } from './components/Home/BlogContent';
import { About } from './components/Home/About';
import Login from './components/pages/Forms/Login';
import Register from './components/pages/Forms/Register';
import Logout from './components/pages/Forms/Logout';
import ResetPassword from './components/pages/Forms/ResetPassword';
import ResetPasswordConfirm from './components/pages/Forms/ResetPasswordConfirm';
import Search from 'antd/lib/input/Search';
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
function App() {
return (
<>
<ToastContainer hideProgressBar={false} position="top-center" autoClose={3000} closeOnClick />
<Router>
<Navbar />
<Routes>
<Route exact path="/" element={<Home />} />
<Route path="/home" element={<Home />} />
<Route path="/book" element={<BooksCard />} />
<Route path="/contact" element={<ContactPage />} />
<Route path="/post/:slug" element={<BlogContent />} />
<Route path="/articles" element={<Articles />} />
<Route path="/search" element={<Search />}/>
<Route exact path="/dashboard" element={<Admin />} />
<Route exact path="/dashboard/create" element={<Create />} />
<Route exact path="/dashboard/edit/:id" element={<Edit />} />
<Route exact path="/dashboard/delete/:id" element={<Delete />} />
<Route path="/about" element={<About />} />
<Route path="/profile" element={<Profile />} />
<Route path="/login" element={<Login />}/>
<Route path="register" element={<Register />} />
<Route path="/logout" element={<Logout />}/>
<Route exact path="/reset-password" element={<ResetPassword />} />
<Route exact path='/password/reset/confirm/:uid/:token' element={<ResetPasswordConfirm />} />
<Route path="/*" element={<Error />} />
</Routes>
<Footer />
</Router>
</>
);
}
export default App;
Merci
Solution du problème
Comme je l'ai écrit dans les commentaires - l'ajout slug
au tableau de dépendances de votre a useEffect
résolu le problème.
Pourquoi donc? Le tableau de dépendances dans useEffect
le crochet est utilisé pour réexécuter le crochet lorsque l'une de ces variables change. Dans votre cas, la modification de l'URL modifie le slug afin que le composant charge de nouvelles données.
I would even remove setData
from this array, because it doesn't do anything as useState
setters don't ever change.
useEffect(() => {
laxiosInstance.get(slug).then((res) => {
setData({ posts: res.data });
});
}, [slug]);
Aucun commentaire:
Enregistrer un commentaire