我正在尝试刷新页面上的结果,但是刷新按钮位于我的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钩子来检查name
或token
的更新。
您可以返回用于从自定义钩子中获取数据的函数:
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
中调用这个新函数来进一步重构