我有一个自定义钩子,我调用16个subreddits在时间,因为我想实现无限滚动。当url页面参数改变时,我想将新数据添加到数组中,然后我映射。但是我找不到正确的打字方式。你们谁能给我指路吗?
类型:
export type Subreddits = [Subreddit];
export type Subreddit = {
id: string;
title: string;
description: string;
};
钩:
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;
这是向set添加新项的正确方法:
setSubredditData((
{ subredditData }) => ({
subredditData: new Set(subredditData).add(response.data)
})
);
将subredditData
类型更改为Array
const [subredditData, setSubredditData] = useState<Array>([])
然后使用;
setSubredditData(subredditData => [...subredditData, ...response.data])
理想情况下,你应该定义响应对象的类型,以便Typescript知道它拥有什么样的数据;
.then((response: ResponseType) => {
工作示例:codesandbox
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;
工作示例:https://codesandbox.io/s/musing-brown-9nf7ne?file=/src/App.js
我找到了解决方案
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;
谢谢大家的帮助