Search code examples
reactjsreact-hooksuse-effectuse-state

Delete elements in state array element in useEffect hook using props values


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.


Solution

  • 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]);