【发布时间】:2020-04-23 01:40:14
【问题描述】:
正如标题所说,使用自定义钩子处理onClick事件的正确方法是什么?
当用户点击搜索按钮时,codesandbox application 将在屏幕上显示新的报价。
function App() {
const [{ data, isLoading, isError }, doFetch] = useDataApi(
"https://api.quotable.io/random"
);
return (
<Fragment>
<button disabled={isLoading} onClick={doFetch}>
Search
</button>
{isError && <div>Something went wrong ...</div>}
{isLoading ? <div>Loading ...</div> : <div>{data.content}</div>}
</Fragment>
);
}
我创建了一个名为 useDataApi() 的自定义钩子,它可以从 API 中获取新的报价。为了在用户单击按钮时更新报价,在useDataApi() 内,我创建了一个handleClick(),它将更改单击值的值以触发重新渲染。而这个handleClick() 函数将返回到App()
const useDataApi = initialUrl => {
const [data, setData] = useState("");
const [click, setClick] = useState(true);
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
const handleClick = () => {
setClick(!click);
};
useEffect(() => {
const fetchData = async () => {
setIsError(false);
setIsLoading(true);
try {
const result = await axios(initialUrl);
setData(result.data);
} catch (error) {
setIsError(true);
}
setIsLoading(false);
};
fetchData();
}, [initialUrl, click]);
return [{ data, isLoading, isError }, handleClick];
};
这是可行的,但是,我认为这不是正确的解决方案。
我还尝试将fetchData() 移出useEffect 并返回fetchData(),它也可以。但是根据React Doc,它说建议将函数移动到useEffect内。
const useDataApi = initialUrl => {
const [data, setData] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
const fetchData = async () => {
setIsError(false);
setIsLoading(true);
try {
const result = await axios(initialUrl);
setData(result.data);
} catch (error) {
setIsError(true);
}
setIsLoading(false);
};
useEffect(() => {
fetchData();
}, []);
return [{ data, isLoading, isError }, fetchData];
};
此外,对于创建这些类型的应用程序,我使用的方式是好的还是有其他正确的解决方案,例如不使用任何 useEffects 或不创建任何自定义 Hook?
谢谢
【问题讨论】:
-
你的问题有点奇怪。对我来说看起来不错。为什么你认为它是错误的?
-
因为我必须在自定义 Hook 中创建一个 handleClick()?我觉得有这个功能来触发重新渲染有点奇怪。
标签: javascript reactjs react-hooks