gpt4 book ai didi

javascript - 一旦功能组件中的状态发生变化,如何触发 Hook ?

转载 作者:行者123 更新时间:2023-12-04 17:16:37 25 4
gpt4 key购买 nike

我正在编写一个自定义分页 Hook ,它将获取 API 并将一些数据返回给我,例如 React Query。相当简单。我要做的是在状态(在本例中为 cursor)更新时触发该 Hook 。

这是钩子(Hook)本身:

import axios from "../api/axios";
import { useEffect, useRef, useState } from "react";

interface FetchInfiniteResourceProps {
// The URL of the API endpoint
url: string;
// Cursor of the page
cursor: number;
// Parameter with which the backend accepts the cursor number
queryParam: string;
// The property on the response which will indicate if the next page exists
nextPageParam: string;

// Other config
config: {
enabled: boolean;
};
}

// Prop types for useFetchInfiniteResource
interface StateProps {
data: any[];
isLoading: boolean;
hasNextPage: boolean;
isFetchingNextPage: boolean;
}

/**
* This function will be used for fetching
* an infinite resource from the back-end
*/
export const useFetchInfiniteResource = ({
url,
cursor,
queryParam,
nextPageParam,
config: { enabled },
}: FetchInfiniteResourceProps) => {
// Creating a new state
const [state, setState] = useState<Partial<StateProps>>({
data: [],
isLoading: true,
hasNextPage: false,
isFetchingNextPage: false,
});

// Method for setting the data
const setData = (newState: []) => setState({ data: newState });

// The function for sending the request
const request = async () => {
// If it's not the first time that this request has triggered
if (!state.isLoading) setState({ ...state, isFetchingNextPage: true });

// Sending the request
const { data: response } = await axios.get(url, {
params: {
// Query paramter
[queryParam]: cursor,
},
});

// Updating the state
setState({
// If it's the first time that this request is invoked
isLoading: state?.isLoading && false,
// Merging the data
data: state?.data?.concat(response.data),
// Checking if the next page exists
hasNextPage: response[nextPageParam] !== null,
// If it's not the first time that the request is invoked then set it to false
isFetchingNextPage: !state?.isLoading && false,
});
};

const requestRef = useRef(async () => await request());

useEffect(() => {
if (enabled) requestRef.current();
}, [enabled]);

// Returning all the items from the state and the function to update the data manually
return { ...state, setData };
};

这是组件:

const SomeComponent = () => {
const [cursor, setCursor] = useState(0);
const {...} = useFetchInfiniteResource({ cursor, ... }); // Problem here

someListener(() => {
setCursor(cursor + 1); // Problem here
});

return ...
}

我认为我滥用了 useEffect 或 useRef Hook ,但到目前为止我也尝试过使用 useCallback Hook 。

谢谢你的帮助

最佳答案

尝试将请求函数包装在 useEffect Hook 中,仅将光标放在依赖项数组中。 ESLint 不会喜欢它,但它应该可以工作。

精简示例:

const useFetchInfiniteResource = ({
cursor,
...
}: FetchInfiniteResourceProps) => {
const [state, setState] = useState<Partial<StateProps>>({ ... });

const setData = (newState: []) => setState({ data: newState });

useEffect(() => {
const request = async () => {
if (!state.isLoading) setState({ ...state, isFetchingNextPage: true });
const { data: response } = await axios.get(url, {
params: {
[queryParam]: cursor,
},
});
setState({ ... });
};

if (enabled) request();
}, [cursor]);

return { ... };
};

关于javascript - 一旦功能组件中的状态发生变化,如何触发 Hook ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68588211/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com