Xin chào mọi người.Thì em đang có một project về khóa học online, vấn đề em đang gặp phải là Fe em viết bằng reactjs và BE là asp.net core api, thì khi bên react, trang body em cho render lần đầu khi chạy sẽ lấy data và gửi về để show ra, nếu lần đầu user vào trang nó vẫn hiển thị bình thường, nhưng giả sử user nhấn sang component khác bằng router, sang component khác cũng giống như sang trang khác ấy, này chắc ai code react sẽ biết, thì khi từ trang đó nếu nhấn nút quay về trang home hoặc là nhấn nút quay về của trình duyệt, sẽ ko có gì để hiển thị, phải f5 nó mới hiện ra lại, dù em đã để nếu thay đổi path thì sẽ reload lại trang đó nhưng ko được, có ai từng gặp vấn đề này giải quyết sao vậy ạ
Vấn đề về reload trong reactjs
Cách giải quyết thì còn tuỳ vào nguyên nhân của bug.
Mà nguyên nhân của tình huống trên thì khả năng cao là do bạn quản lý trạng thái (states) không đúng cách dẫn đến component không biết được có sự thay đổi của trạng thái khi di chuyển qua lại giữa các trang.
Tuy bạn đã mô tả rõ vấn đề gặp phải, nhưng do không cung cấp thêm cách để tái hiện vấn đề (aka. steps to reproduce), nên mình chỉ giúp đc nhiêu đó th. Muốn rõ hơn thì bạn cung cấp thêm source code, hoặc phiên bản tối giản của source code đủ để tái hiện tình huống trên nhé.
Lần sau đăng source code dạng văn bản nhé, chưa biết cách đăng như nào thì tham khảo ở đây.
Có 4 vấn đề ở source code của bạn:
-
fetchData()
có thực thi hay không phụ thuộc vào trạng thái củaisMonted
, mà phần xử lý liên quan đếnisMounted
như nào thì bạn k cung cấp. - ở trong xử lý
useEffect()
có chứa hàmfetchData()
bạn có sử dụng đến trạng tháiisMounted
nhưng lại không đưa nó vào danh sách trạng thái phụ thuộc dependencies array (chú thích ngay đó rồi, mà không chắc bạn có hiểu dòng chú thích đó k). - theo như cú pháp của bạn có vẻ đang dùng cú pháp cũ của React Router, nên quản lý bằng cách sử dụng
RouterProvider
vàcreateBrowserRouter
. Nó giúp bạn dễ dàng quản lý các routes ở một chỗ. - cách khai báo function component của bạn chưa có sự thống nhất. Khi thì dùng
function Component()
, khi thì dùng arrow function.
const Body = () => {
const [products, setProducts] = useState([]);
const location = useLocation();
const cachedData = localStorage.getItem('products');
useEffect(() =>{
const fetchData = async () => {
try {
const response = await axios.get('https://localhost:7298/api/GetData');
setProducts(response.data);
localStorage.setItem('products', JSON.stringify(response.data));
} catch (error) {
console.error('Có lỗi xảy ra khi lấy dữ liệu:', error);
}
};
fetchData();
},[]);, const router = createBrowserRouter([
{
path: "/",
element: <AppLayout />,
children: [
{ index: true, element: <Body /> },
{ path: "/", element: <Body /> },
{ path: "cart", element: <Cart /> },
{ path: "dog", element: <ProfileSettings /> },
{ path: "teachingcourse", element: <CourseListByTeaching /> },
{ path: "course", element: <CourseDetail /> },
{ path: "study", element: <LearningPage /> },
{ path: "courseProgram", element: <CourseProgram /> },
{
element: <PrivateRoute />,
children: [
// Private routes go here
// { path: "checkout", element: <ProductDetail /> },
]
}
]
},
{ path: "/custom", element: <CustomHeader /> },
{ path: "/coursecontent", element: <CourseContent /> },
{ path: "/you", element: <CourseLayout /> },
{ path: "/test", element: <RandomDogImage /> },
{ path: "/login", element: <Login /> },
{ path: "/register", element: <Register /> }
]);
function AppRoutes() {
const [isAuthenticated, setIsAuthenticated] = useState(!!localStorage.getItem('token'));
const [selectState, setState] = useState(true);
return (
<AppProvider>
<RouterProvider router={router} />
</AppProvider>
);
}
export default AppRoutes;,
function AppLayout() {
return (
<div>
<TokenChecker/>
<CustomHeader />
<Outlet /> {/* This is where the main content will be rendered */}
<Footer />
</div>
);
}
export default AppLayout; dạ vâng, thì đây là đoạn code hiện tại ạ, em để là khi render lần đầu thì mặc định tải lại trang khi quay lại, nên em để useeffect là ko tham số, em có sài applayout để bao bọc và để nó trong approute bằng cái routeProvider mới của react như a nói, chỉ là em thử trong console, thì data khi em quay lại vẫn show ra, nhưng ở trang thì ko hiện gì, cứ phải f5 nó mới có lại ạ
Với đoạn code như này thì không thể nào tái hiện lại được lỗi của bạn. Toàn những thông tin mấu chốt thì lại bị lược đi.
chỉ là em thử trong console, thì data khi em quay lại vẫn show ra, nhưng ở trang thì ko hiện gì, cứ phải f5 nó mới có lại ạ
Bạn chuyển trang như nào? Dữ liệu được render như nào? Nếu vẫn log ra được nghĩa là đã lấy được dữ liệu thành công rồi đúng không? Vậy có lẽ vấn đề ở chỗ cách bạn render.
Có vẻ hơi khó khăn với bạn, nhưng bạn có thể tái hiện lại lỗi trên các trang js playground online như https://jsfiddle.net/, https://codesandbox.io/ được không?
Dòng code lấy dữ liệu ở local có thể thay bằng:
const fakeData = () =>
new Promise((res) => {
setTimeout(() => {
res({
data: {
example: ["data"],
},
});
}, 200);
});
// const response = await axios.get('https://localhost:7298/api/GetData');
const response = await fakeData()
dạ, đúng rồi, hình như do cách nó render ạ, như ảnh này thì là lần đầu vô trang e có để console thì ra data
, còn đây là ảnh 2 , em có sang component khác bằng roiter rồi nhấn quay lại, thì vẫn log ra, nhưng data ko hiển thị ạ, đây là vấn để em đang gặp phải ạ, phần body em giữ nguyên như lúc gửi a ko thay đổi điều kiện gìVấn đề ở phần render, nhưng render như nào thì k nói, code Body ở trên có thấy chỗ nào render đâu.
Còn có log gì đỏ lòm kia, sao k đưa nốt ra.
thì đây là phần body remder ra đây ạ
{products.length > 0 ? (
<>
{products.map((course, index) => (
<Link
key={index}
to="/course"
state={{courseId:course.courseId}}
>
<div key={index} className="single-popular-course">
<div className="thumb">
<img className="f-img img-fluid mx-auto" src={course.thumbnailImage} alt="" />
</div >
<div className="details">
<div className="justify-content-between mb-20">
<p className="name">{course.title}</p>
<p>{course.instructorName}</p>
<p className="name">4.6 <FontAwesomeIcon icon={faStar} /></p>
<Link onClick={(e) => {
e.preventDefault();
addToCart(course);
}} >
<a className='chencart'>
<p className="name">đ {course.price.toLocaleString('vi-VN')}</p>
<span><FontAwesomeIcon icon={faCartPlus}/>
</span>
</a>
</Link>
cái bug đỏ nó cũng ko liên quan đến render nên e chưa fix ấy a
Với những đoạn code bạn cho mình xem từ đầu đến giờ thì chưa thấy chỗ nào có thể gây ra lỗi reload cả. Chưa kể đến code còn không chạy được (thiếu đầu thiếu đuôi).
Bạn có thể lược bớt những phần không quan trọng nhưng vẫn phải đảm bảo code chạy thành luồng hoàn chỉnh, mà không chắc bạn có biết được đoạn nào quan trọng hay không nữa.
Chắc mình sẽ đợi đến khi nào bạn tái hiện được lỗi reload mà bạn gặp phải trên https://codesandbox.io/ và share link lên đây, thì chúng ta hãy tiếp tục câu chuyện.
Có phải chủ topic sử dụng ReactJS mà không có kiến thức nền JavaScript, TypeScript? Tui đoán khả năng như vậy.
Lý do: nếu anh ta có kiến thức nền JavaScript thì anh ta phải hiểu rằng debug thực chất ReactJS sẽ gọi những hàm JavaScript. Khi có event nó phản ứng -> để gỡ rối được, ta cần xen vào giữa chỗ event <-> react để xem mọi thứ có thông suốt? Nếu thông, vấn đề còn lại là DOM đã map qua HTML chuẩn chinh chưa?
Vậy, ở đây cần rà soát là: 1) Event có xảy ra? 2) Có rồi thì có cái gì bắt event này để react? 3) Có phản ứng rồi thì liệu DOM có bị hidden, invisible? Hoặc error gì đó không mà không chịu hiện lên giao diện? Có khi nào hiện lên nhưng vì CSS có margin nằm ngoài khung màn hình hoặc z-index chồng lấn? Gì mà cứ để console ra data <= vô nghĩa. Vì data không phải là cái cần thấy mà thấy ở đây là nội dung, vắng data thì tạm dùng fake data để test, không thấy hiện màn hình thì không biết vì sao? Để rồi lên đây mô tả nghe cứ lạ lẫm thế nào ấy?
Chưa kể là anh ta cũng không biết sử dụng công cụ debug như DevTools và/ hoặc các Addons, Extension cho trình duyệt - cái mà được tạo ra dành hỗ trợ, ví dụ như React Developer Tools? Vì lẽ ra nếu anh ta hiểu được vấn đề chung của dân lập trình, anh ta sẽ phải đặt các breakpoint và đăng code kèm vài chỗ breakpoint lên đây để đồng động ủn đít dễ hơn.
bữa giờ em fix thử thì hình như là do api em viết bên backend, em sài thử api dog free trên internet, ra vào lại vẫn load như bình thường, riêng api em thì lại không được
có vẻ vấn đề là do api em viết bên backend, mặc dù fe gọi nhưng nó ko hiện , riêng api free trên mạng thì vẫn load đều ra bình thường
em có thử sài api được public trên internet thì vẫn có data hiển thị ra khi quay lại trang ấy, hình như lỗi trong hình ko phải, em có check rồi ạ
Này khả năng là message của chrome extension nên ko liên quan thật