如何从子组件调用 React Hook 来刷新结果
How to call a React Hook from a child component to refresh results
我正在尝试刷新页面上的结果,但刷新按钮位于最初调用我的 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>
);
};
我的 Awesome 钩子看起来像这样
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
.
现在,就触发数据请求而言,您的挂钩与任一组件之间没有任何联系。我的建议是向您的挂钩添加一个函数,该函数将调用您的 api 和 return 挂钩中的函数
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);
并将其作为 prop 传递给 Header
组件,您只需将其用作
<Button
onClick={callAnApiHandler}
>
Refresh
</Button>
然后您可以在 useEffect
中调用这个新函数以进一步重构
您可以 return 用于从自定义挂钩中获取数据的函数:
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>
);
};
我正在尝试刷新页面上的结果,但刷新按钮位于最初调用我的 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>
);
};
我的 Awesome 钩子看起来像这样
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
.
现在,就触发数据请求而言,您的挂钩与任一组件之间没有任何联系。我的建议是向您的挂钩添加一个函数,该函数将调用您的 api 和 return 挂钩中的函数
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);
并将其作为 prop 传递给 Header
组件,您只需将其用作
<Button
onClick={callAnApiHandler}
>
Refresh
</Button>
然后您可以在 useEffect
中调用这个新函数以进一步重构
您可以 return 用于从自定义挂钩中获取数据的函数:
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>
);
};