1

I have read several cases on stackoverflow regarding missing dependencies in useEffect: example : How to fix missing dependency warning when using useEffect React Hook?

Now the case I have is, I use useEffect for pagination: Here's the source code:

react-router-dom configuration

  { path: "/note", name: "My Note", exact: true, Component: Note },

Note Component

const Note = (props) => {
  const getQueryParams = () => {
    return window.location.search.replace("?", "").split("&").reduce((r, e) => ((r[e.split("=")[0]] = decodeURIComponent(e.split("=")[1])), r),
        {}
    );
  };

  const MySwal = withReactContent(Swal);
  const history = useHistory();

  // Get Queries On URL
  const { page: paramsPage, "per-page": paramsPerPage } = getQueryParams();
  
  // Queries as state
  const [queryPage, setQueryPage] = useState(
    paramsPage === undefined ? 1 : paramsPage
  );
  const [queryPerPage, setQueryPerPage] = useState(
    paramsPerPage === undefined ? 10 : paramsPerPage
  );

  // Hold Data Records as state
  const [notes, setNotes] = useState({
    loading: false,
    data: [],
    totalData: 0,
  });

  useEffect(() => {
    console.log(queryPage, queryPerPage);
    setNotes({
      ...notes,
      loading: true,
    });

    // Fetching data from API
    NoteDataService.getAll(queryPage, queryPerPage)
      .then((response) => {
        setNotes({
          loading: false,
          data: response.data,
          totalData: parseInt(response.headers["x-pagination-total-count"]),
        });

        return true;
      })
      .catch((e) => {
        MySwal.fire({
          title: e.response.status + " | " + e.response.statusText,
          text: e.response.data,
        });
      });

    return false;
  }, [queryPage, queryPerPage]);

  const { loading, data, totalData } = notes;

  ...

So there are two problems here:

  1. There is a warning React Hook use Effect has missing dependencies: 'MySwal' and 'notes'. Either include them or remove the dependency array. You can also do a functional update 'setNotes (n => ...)' if you only need 'notes' in the 'setNotes' call. If I add notes and MySwal as dependencies, it gives me a continuous loop.
  2. When I access the "note" page, the Note component will be rendered. Then, with pagination: / note? Page = 2 & per-page = 10, it went perfectly. However, when returning to "/ note" the page does not experience a re-render. Strangely, if a route like this / note? Page = 1 & per-page = 10, returns perfectly. Does my useEffect not run after pagination?
Fadly Dzil
  • 2,154
  • 3
  • 34
  • 85
  • Replace your first setNote inside useEffect `setNotes(prevNotes => ({ ...prevNotes, loading: true }))`; You don't need notes in useEffect. It is only one problem. – Kirill Skomarovskiy Jan 23 '21 at 20:41
  • Oke, how about MySwal component ? – Fadly Dzil Jan 23 '21 at 20:46
  • ``` const MySwalRef = useRef(null); const MySwal = withReactContent(Swal); useEffect(() => { MySwalRef.current = MySwal; }, [MySwal]); // your useEffect; useEffect(() => { NoteDataService.getAll(queryPage, queryPerPage) .then() .catch(() => { MySwalRef.current.fire(); }); }, []); ``` – Kirill Skomarovskiy Jan 23 '21 at 20:56
  • It works, but I kinda un-familiar with useRef, let me learn it first – Fadly Dzil Jan 23 '21 at 21:06

1 Answers1

1

First of all, move your API call inside of useEffect. After your data is fetched, then you can change the state.

useEffect(() => {
//Fetch the data here
//setState here 
},[]) //if this array is empty, you make the api call just once, when the `component mounts`

Second Argument of useEffect is a dependancy array, if you don't pass it, your useEffect will trigger in every render and update, which is not good. If you parss an empty array, then it makes just one call, if you pass a value, then react renders only if the passed value is changed.

Tigran Petrosyan
  • 524
  • 4
  • 14