Vấn đề về reload trong reactjs

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 ạ

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é.

4 Likes

Screenshot 2024-10-09 091903 Screenshot 2024-10-09 091912 dạ, thì em có 1 app layout để bọc toàn bộ component để hiển thị header ở các trang khác. thì app layout em để nó nằm trong approute chính, từ approute em để ở app.js, ko biết vấn đề do đâu ạ

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ủa isMonted, mà phần xử lý liên quan đến isMounted như nào thì bạn k cung cấp.
  • ở trong xử lý useEffect() có chứa hàm fetchData() bạn có sử dụng đến trạng thái isMounted 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 RouterProvidercreateBrowserRouter. 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.

1 Like

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.

1 Like

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.

1 Like

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

Ờm, và mình đoán k nhầm thì nó ở chỗ mà bạn bảo không liên quan này này. :upside_down_face:

1 Like

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 :smiley:

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?