Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

filter object array with other object array – React Typescript

I’m getting data from the server and saving it in 2 different states so one will show all the data received and the other one will show it as pagination.

The array type is:

type ArrayType = {
  name:string;
  id:number;
  link:string;
}

Now the first array has over 200 objects inside of it, while the second array has only 15 objects inside of it.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I’m trying to loop and filter it but it returns the lasts objects + the same last Objects:

interface ComponentState {
  total?: ArrayType[];
  few?: ArrayType[];
}

const Component = () => {
  const isMounted = useRef(true);
  const [state, setState] = useState<ComponentState>({});

  useEffect(() => {
    const updateState = async () => {
      const res = await fetch(FetchUrl);
      const data = await res.json();
      setState((prevState) => ({
        ...prevState,
        total: data,
        few: data.slice(0, 10),
      }));
    };

    if (isMounted.current) updateState();

    return () => {
      isMounted.current = false;
    };
  }, []);
};

Now When I want to update The state.few I’m trying to do:

const onButtonClick = () => {
    setState((prevState) => ({
      ...prevState,
      few: [
        ...state.few!,
        ...state.total!.filter((item) =>
          state.few!.filter((prevItem) => prevItem !== item)
        ).slice(0,10),
      ],
    }));
  };

  console.log(state.few);

  return <button onClick={onButtonClick}></button>;

And I keep getting the first 10 items of state.total instead of the next 10 items in the list

>Solution :

In React you should not store variables that can be calculated from the state in another state.

So what’s the information you need to implement a ‘load more’ button?

  • all the list elements
  • the index up to which you want to render

These are your state variables. Which items to render can be calculated from those.

So I would implement your component as follows:

const Component = ()=> {
  const [items, setItems] = useState([]);
  const [showN, setShowN] = useState(10);

  // calculate elements to render from state
  const toRender = items.slice(0, showN);

  useEffect(()=>{
    // your isMounted ref does not work. You need to check if the component is mounted before setting the state, not before firing the async function 
    let stillMounted = true;
    const updateState = async () => {
      const res = await fetch(FetchUrl);
      const data = await res.json();
      // check if still mounted
      if(!stillMounted) return;
      setItems(data);
      };
    updateState();
    // on unmount, this function will be called, preventing a state update on an unmounted component
    return ()=>stillMounted = false;
  }, []);
  
  // just update the showN state when the button is clicked
  const onButtonClick = ()=>{
    setShowN(before=>before + 10);
  }
  // return something
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading