6

In many of my components, I have to use token from store to get data and represent it (header menu, footer menu, products on page, slider images, etc.). What I am trying to do is to get this data only if I don't have it, but React keeps sending requests every time token changes (as token is dependency), even though I clearly put condition and I can see it if I console.log it. What am I doing wrong?

const [cities, setCities] = useState([]); useEffect(() => { if (!cities.length) { fetch(`.....&token=${props.token}`) .then(response => response.json()) .then(data => { if (data.data.results) { setCities(data.data.results.cities) } }) } }, [props.token, cities.length]); 
1
  • Since you set cities on every re-render, cities is always a new object, thus cities.length is not the same as the previous one. Also if(!cities.length) is always true since cities is always defined, initially the length is 0, which still returns true. What you could do instead is if(cities.length<1) Commented Nov 27, 2019 at 18:16

2 Answers 2

2

The cities will be empty on first render anyway, so you don't need to check for its length and specify it as a dependency:

const [cities, setCities] = useState([]); useEffect(() => { fetch(`.....&token=${props.token}`) .then(response => response.json()) .then(data => { if (data.data.results) { setCities(data.data.results.cities) } }) }, [props.token]); 

You can also memoize the token to prevent it from triggering the useEffect callback:

const token = useMemo(() => props.token, []); 
Sign up to request clarification or add additional context in comments.

Comments

0

// EDITED BECAUSE OF THE COMMENTS

// should be outside of the function let timesExecuted = 0 function fetch () { useEffect(() => { if(props.token){ timesExecuted = timesExecuted + 1 } if (timesExecuted === 1) { fetch(`.....&token=${props.token}`) .then(response => response.json()) .then(data => { if (data.data.results) { setCities(data.data.results.cities) } }) } }, [props.token]); } 

SO IT WILL COME every time BUT BE EXECUTED ONLY WHEN prop.token IS OKEY (feel free to modify the first IF based on token validations).

4 Comments

It is to make sure that token is there, as token is also requested in other component.
do you need to get the cities every time the token changes? Or you need it only 1 time ?
Only one time, but I don't know if I have token already in my store as it is also requested when app mounts. So basically I need it as a dependency, so when it is there, I send request.
Done i edited my answer based on your needs, feel free to upvote and mark as solution answer if it worked

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.