如何从子组件中调用React Hook来刷新结果



我正在尝试刷新页面上的结果,但是刷新按钮位于我的React Hook最初调用的子组件中。

export const ParentComponent = ({
}) => {
const infoINeed = useSelector(getInfoINeed);
const { error, isLoading, data } = useMyAwesomeHook(infoINeed.name);
return (
<div>
<Header/>
<Body className={classes.body}>
<div>Hello Stack overflow</div>
<Body>
</div>
);
};

My Awesome hook是这样的

export const useDogCounts = (name: string | undefined) => {
const { data: token, error: authError } = useAuthHook();
const [error, setError] = useState<Error | null>(null);
const [isLoading, setLoading] = useState(true);
useEffect(() => {
const fetchMyData = async () => {
const request = myRequest(name);
try {
setLoading(true);
const counts = callMyFunction()
setMyData(counts);
setLoading(false);
} catch (requestError) {
if (requestError === null) {
setError(requestError);
} else {
throw requestError;
}
setLoading(false);
}
};
fetchMyData();
}, [name, token]);

return {
data: dogCounts,
error,
isLoading,
};
};

然后在我的<Header/>组件中,我有一个刷新按钮,我想调用钩子。

import React, { FC } from 'react';
import { Button } from '@material-ui/core';
export const Header: FC<HeaderProps> = ({}) => {

return (
<Page.Header className={classes.headerWrapper}>
<Page.Title>Dog Counts</Page.Title>
<Button
onClick={() => {}} // functionality to go here
>
Refresh
</Button>

</Header>
);
};

我尝试了几种方法,包括将一个变量传递到名为refresh的useDogCount钩子中,Header组件在状态中改变以触发主钩子中的useEffect钩子。这样做似乎有点混乱,并引入一个新变量来跟踪。

我也在其他地方实现了类似的东西,在不同的时间里,我没有在我的自定义钩子中使用useEffect钩子,而是将Promise传递回所需的地方来刷新它。但是,我需要这里的useEffect钩子来检查nametoken的更新。

您可以返回用于从自定义钩子中获取数据的函数:

export const ParentComponent = () => {
const infoINeed = useSelector(getInfoINeed);
const { error, isLoading, data, fetchData } = useMyAwesomeHook(infoINeed.name);
return (
<div>
<Header onClickRefresh={fetchData}/>
<Body className={classes.body}>
<div>Hello Stack overflow</div>
<Body>
</div>
);
};
export const useDogCounts = (name: string | undefined) => {
const { data: token, error: authError } = useAuthHook();
const [error, setError] = useState<Error | null>(null);
const [isLoading, setLoading] = useState(true);
const fetchData = useCallback(async () => {
... // code to fetch the data
}, [name, token]);
useEffect(fetchData, [fetchData]);
return {
data: dogCounts,
fetchData,
error,
isLoading,
};
};
export const Header: FC<HeaderProps> = ({onClickRefresh}) => {
return (
<Page.Header className={classes.headerWrapper}>
<Page.Title>Dog Counts</Page.Title>
<Button onClick={onClickRefresh}>
Refresh
</Button>
</Header>
);
};

现在,在触发数据请求方面,钩子和任何组件之间都没有连接。我的建议是在钩子中添加一个函数它将调用你的api并从钩子

返回该函数
export const useDogCounts = (name: string | undefined) => {
const { data: token, error: authError } = useAuthHook();
const [error, setError] = useState<Error | null>(null);
const [isLoading, setLoading] = useState(true);
const callAnApi = async () => {
// ... body of the useEffect
}
useEffect(() => {
const fetchMyData = async () => {
const request = myRequest(name);
try {
setLoading(true);
const counts = callMyFunction()
setMyData(counts);
setLoading(false);
} catch (requestError) {
if (requestError === null) {
setError(requestError);
} else {
throw requestError;
}
setLoading(false);
}
};
fetchMyData();
}, [name, token]);

return {
data: dogCounts,
error,
isLoading,
};
};

然后在ParentComponent中将其解构为

const { error, isLoading, data, callAnApi } = useMyAwesomeHook(infoINeed.name);

并将其传递给Header组件作为道具,您只需使用它作为

<Button
onClick={callAnApiHandler}
>
Refresh
</Button>

然后你可以在useEffect中调用这个新函数来进一步重构

最新更新