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