Home > database >  React Typescript. The right way to push new objects form api to array with existing objects without
React Typescript. The right way to push new objects form api to array with existing objects without

Time:05-08

I have a custom hook where I call 16 subreddits at the time because I want to implement an infinite scroll. When the url page parameter change I want to add the new data to the array witch then I map. But I cant find the right way to do it with typescript. Can some of you guys show me the right way?

The types:

export type Subreddits = [Subreddit];
export type Subreddit = {
id: string;
title: string;
description: string;
}; 

The Hook:

function useSubreddit() {
  let [subredditData, setSubredditData] = useState<any>([]);
  const [loadingSubbredits, setLoadingSubreddits] = useState(false);
  const [subredditError, setSubredditError] = useState(null);
  const dispatch = useDispatch();
  const url =
    "https://6040c786f34cf600173c8cb7.mockapi.io/subreddits?page=1&limit=16";

  useEffect(() => {
    setLoadingSubreddits(true);
    axios
      .get(url)
      .then((response) => {
        setSubredditData(
          (subredditData = [ new Set([...subredditData, ...response.data])])
        );
        dispatch(setSubredditsData(response.data));
      })
      .catch((err) => {
        setSubredditError(err);
      })
      .finally(() => setLoadingSubreddits(false));
  }, [url]);

  return { loadingSubbredits, subredditError, subredditData };
}

export default useSubreddit;

CodePudding user response:

This is the right way to add new item to set:

setSubredditData((
    { subredditData }) => ({
        subredditData: new Set(subredditData).add(response.data)
      })
);

CodePudding user response:

Change subredditData type to Array

const [subredditData, setSubredditData] = useState<Array>([])

Then use;

setSubredditData(subredditData => [...subredditData, ...response.data])

Ideally you should define the type of response object so Typescript knows what kind of data it has;

.then((response: ResponseType) => {

Working example: codesandbox

CodePudding user response:

import { useState, useEffect } from "react";
import axios from "axios";

function useSubreddit() {
  let [subredditData, setSubredditData] = useState({});
  const [loadingSubbredits, setLoadingSubreddits] = useState(false);
  const [subredditError, setSubredditError] = useState(null);
  //console.log(subredditData);
  const url =
    "https://6040c786f34cf600173c8cb7.mockapi.io/subreddits?page=1&limit=16";

  useEffect(() => { 
    setLoadingSubreddits(true);
    axios
      .get(url)
      .then((response) => {
        const result = response.data?.reduce((prev,curr) => ({ ...prev, ...{ [curr.id]: curr }}),{});
       
        setSubredditData((subredditData) => ({ ...subredditData, ...result }));
      })
      .catch((err) => {
        setSubredditError(err);
      })
      .finally(() => setLoadingSubreddits(false));
  }, [url]);

  return { loadingSubbredits, subredditError, subredditData:Object.values(subredditData) };
}

export default useSubreddit;

working example: https://codesandbox.io/s/musing-brown-9nf7ne?file=/src/App.js

CodePudding user response:

I found the solution

function useSubreddit() {
  const [subredditData, setSubredditData] = useState<Array<any>>([])
  const [loadingSubbredits, setLoadingSubreddits] = useState(false);
  const [subredditError, setSubredditError] = useState(null);
  const dispatch = useDispatch();
  const url =
    "https://6040c786f34cf600173c8cb7.mockapi.io/subreddits?page=1&limit=4";

  useEffect(() => {
    setLoadingSubreddits(true);
    axios
      .get(url)
      .then((response: SubredditsResponse) => {
        setSubredditData(Array.from( new Set([ ...subredditData, ...response.data])))
        dispatch(setSubredditsData(response.data));
      })
      .catch((err) => {
        setSubredditError(err);
      })
      .finally(() => setLoadingSubreddits(false));
  }, [url]);

  return { loadingSubbredits, subredditError, subredditData };
}

export default useSubreddit;

Thank you for your help guys

  • Related