3

I am trying to delete items from state variable in useEffect using the props comming to the component. I want to take initial values from state variable and then delete elements in that array and set the state variable again to new value. But When I don't pass the state variable in dependency array it is throwing warning as React Hook useEffect has a missing dependency: 'abc'. Either include it or remove the dependency array and when I pass it, It goes in infinite loop which I think is correct because of useeffect working. This is the useffect I am trying:

const [abc, setAbc] = useState([]);

useEffect(() => {
    axios.get(url).then(res => setAbc(res));
}, [props.bbb])

useEffect(() => {
    if(props.xyz) {
         let aaa = abc.filter(key => key.id === props.xyz);
         setAbc(aaa);
    }
}, [props.xyz])

Is there something I am missing here? Is there any better way to do this?

Thanks in advance.

6
  • 1
    you can use setAbc(currentAbc => currentAbc.filter(key => key.id === props.xyz)) and not provide abc as a dependency. Commented Jul 22, 2021 at 5:44
  • Curios, why do you have two useEffect hooks that have the same dependency and update the same state? Which do you want to win out and update state? Commented Jul 22, 2021 at 5:55
  • I assumed the two useEffects should be one, I'm reading the intended logic as "On change of XYZ reload complete list and then filter based on XYZ" would need more information to be sure. Commented Jul 22, 2021 at 6:01
  • @JacobSmit I don't disagree, other than the first seems to be more the typical fetch data when mounting otherwise it doesn't make sense to run both each time the xyz prop updates. The promise chain of the first will overwrite any filtering the second did since it's asynchronous. Commented Jul 22, 2021 at 6:03
  • Hey. Actually I added the same variables here bymistake. Updated the code. Both use effect have different dependencies. Commented Jul 22, 2021 at 11:41

1 Answer 1

1

Correct, including a dependency that the effect updates will likely cause render looping. Use a functional state update to eliminate the need for abc as a dependency.

useEffect(() => {
  if (props.xyz) {
    setAbc(abc => abc.filter(key => key.id === props.xyz));
  }
}, [props.xyz]);

Since the first useEffect doesn't actually reference props I'm going to maybe assume you meant to only call this on mount. You can do this by using an empty dependency array.

useEffect(() => {
  axios.get(url).then(res => setAbc(res));
}, []);

Update

If you are wanting to fetch abc and filter each time the props.xyz dependency updates then use a single useEffect hook and filter the result before updating state.

useEffect(() => {
  axios.get(url)
    .then(res => {
      if (props.xyz) {
        setAbc(res.filter(key => key.id === props.xyz));
      } else {
        setAbc(res);
      }
    });
}, [props.xyz]);
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. Using abc like setAbc(abc => abc.filter(key => key.id === props.xyz)) worked.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.