0

hi this is my code: https://codesandbox.io/s/busy-tdd-e8s1ej?file=/src/App.js

for the react-router-dom, I used the ver5.2+.

I couldn't for the life of me figure out the missing dependency, I try searching for answers here but it told me to add me to the dependency to no avail.

I appreciate any enlighten on this issue, thank you

jack601
  • 11
  • 4

3 Answers3

1

because you're using something that is defined outside of useEffect (in this case fetchProduct function), react will throw a warning saying if something changes inside the fetchProduct function, useEffect will not catch that change. for example: let's say your match.params.id inside fetchProduct is equal to 1 when the page first loaded, but later on match.params.id becomes 2, the fetchProduct function inside useEffect will still use 1 as match.params.id because useEffect didn't catch the changes.

so to solve the warning, there are 2 options. first is to write the fetchProduct function logic inside useEffect:

useEffect(() => {
  axios
    .get(`https://fakestoreapi.com/products/?id=${match.params.id}`)
    .then((res) => {
      setData(res.data);
      console.log(res.data);
    })
    .catch((err) => console.log(err));
}, [match.params.id]);

having match.params.id in dependency array to make sure useEffect is up to date.

but if you need to reuse the fetchProduct function, then you should do something like:

const fetchProduct = useCallback(() => {
  axios
    .get(`https://fakestoreapi.com/products/?id=${match.params.id}`) // use match to get product id
    .then((res) => {
      setData(res.data);
      console.log(res.data);
    })
    .catch((err) => console.log(err));
}, [match.params.id]);

useEffect(() => {
  fetchProduct();
}, [fetchProduct]);
Layhout
  • 1,445
  • 1
  • 3
  • 16
  • Hi @Layhout, thanks for the efforts! I understand it a bit better now, I tried to change it, but upon clicking the link, I did not manage to get just a single product page (products/1 e.g.) – jack601 Jan 11 '23 at 08:08
  • that is something to do with `react-router-dom`. – Layhout Jan 11 '23 at 08:15
  • just [found](https://stackoverflow.com/a/71835644/17308201) out that it is a bug. turn off `StrictMode` will fix it. – Layhout Jan 11 '23 at 08:31
  • in fact, you don't need to turn off `StrictMode`. move the `` tag from `index.js` to `app.js` and put it between `` and `
    `.
    – Layhout Jan 11 '23 at 08:47
  • hi I have move it, I tried in vs code (I have also upgraded react-router-dom to v6) but I get >> No routes matched location "/products/4" – jack601 Jan 11 '23 at 08:56
  • the syntax of `react-route-dom` [v5](https://v5.reactrouter.com/web/guides/quick-start) and [v6](https://reactrouter.com/en/main/start/tutorial) are different. you need pick one and stick with it. – Layhout Jan 11 '23 at 09:00
  • if you pick v6, you need to undo the move `` tag and rewrite your `app.js`. – Layhout Jan 11 '23 at 09:03
  • must I use match or useParams to find id? or both are fine? in v6 – jack601 Jan 11 '23 at 09:48
  • yes, i think that the only way. – Layhout Jan 11 '23 at 09:49
0

It is a warning, Kindly look through the documentation of useEffect()

https://reactjs.org/docs/hooks-effect.html.

Whenever you add in a dependency in the array, it will watch all those values and it will re-run the useEffect hook. whenever that particular value/dependency changes.

https://reactjs.org/docs/hooks-effect.html#:~:text=React%20to%20skip%20applying%20an%20effect%20if%20certain%20values%20haven%E2%80%99t%20changed%20between%20re%2Drenders

SARAN SURYA
  • 534
  • 5
  • 14
0

You are using the fetchProduct function in your effect, so it is a dependency. The error message should tell you that.

One way to fix it is to move the fetchProduct function inside the effect. Then match will become a dependency of the effect, but you probably want that as if match changes you most likely want to fetch the new product.

useEffect(() => {
  // function fetchProducts
  const fetchProduct = () => {
    axios
      .get(`https://fakestoreapi.com/products/?id=${match.params.id}`) // use match to get product id
      .then((res) => {
        setData(res.data);
        console.log(res.data);
      })
      .catch((err) => console.log(err));
  };
  fetchProduct();
}, [match]);
Guillaume Brunerie
  • 4,676
  • 3
  • 24
  • 32