繁体   English   中英

React:useEffect 仅在数据更改时调用

[英]React: useEffect to only invoke when data changes

我有一个多页应用程序。 当我在dashboard/globaldashboard/my-posts之间单击时,将调用 useEffect。 因此,我的应用程序不断调用我的 fetch 并需要一段时间来加载。

有没有办法只在找到新数据时调用 useEffect ?

我尝试将 myRecipes 和 AllRecipes 添加到 useEffect 依赖项,但track promise的加载指示符正在无限运行。

import React, {
  useState, useEffect, useContext, useMemo,
} from 'react';
import { v1 as uuidv1 } from 'uuid';
import { trackPromise } from 'react-promise-tracker';
import LoadingIndicator from '../utils/LoadingIndicator';
import DashboardHeader from './DashboardHeader';
import '../App.css';
import Post from './Post';
import CreateForm from '../create-recipe/CreateForm';
import RecipeService from '../../service/RecipeService';
import { AuthContext } from '../../context/AuthContext';

export default function Dashboard() {
  const { isAuthenticated } = useContext(AuthContext);
  const [allRecipes, setAllRecipes] = useState([]);
  const [myRecipes, setMyRecipes] = useState([]);
  const currentUrl = window.location.pathname;

  useEffect(() => {
    if (currentUrl === '/dashboard/global') {
      trackPromise(
        RecipeService.getAllRecipes()
          .then((data) => {
            setAllRecipes(data);
          }),
      );
    } else if (currentUrl === '/dashboard/my-posts' && isAuthenticated === true) {
      trackPromise(
        RecipeService.getRecipes()
          .then((data) => {
            setMyRecipes(data);
          }),
      );
    }
  }, [currentUrl, allRecipes, myRecipes]);

  return (
    <>
      <div className="dashboard">
        <DashboardHeader />
        {currentUrl === '/dashboard/my-posts' && !isAuthenticated
          ? <h2 className="dashboard__unauthenticated-msg">Please Login To See Your Recipes</h2>
          : null}
        <div className="created-posts">
          {currentUrl === '/dashboard/global' && allRecipes
            ? allRecipes.map((recipe) => <Post recipe={recipe} key={uuidv1()} />)
            : null}
          {currentUrl === '/dashboard/my-posts' && myRecipes.recipes
            ? myRecipes.recipes.map((recipe) => <Post recipe={recipe} key={uuidv1()} />)
            : null}
          {myRecipes.recipes && allRecipes
            ? null : <LoadingIndicator />}
        </div>
        {currentUrl === '/dashboard/create' ? <CreateForm /> : null}
      </div>
    </>
  );
}

更好的架构可以帮助您解决此组件的问题。 当 URL 发生变化时,您应该使用路由器并加载不同的组件。 然后,您可以进行适当的 API 调用,并为该页面呈现适当的 JSX。

AllRecipesmyRecipes不应该是该 useEffect 的依赖项,因为当它被调用时,它将更新这些状态并再次触发自身。

如果您想根据源数据是否更改来调用 function,我建议您将选择器与 redux 一起使用。

简而言之,选择器是检测当前参数变化的记忆函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM