我刚刚开始使用React,并编写了一些HOC。然后我读到功能组件和挂钩是前进的建议方法,所以我决定重写我的HOC。
我使用的常见模式是:
class MyButton(Component) {
...
handleClick = () => {
setState({busy: True}, () => {
fetchAPI().then(
(results) => {
setState({results: results, errs: [], busy: False});
},
(err) => {
setState({errs: err, busy: False});
});
});
};
render() {
return(
<Button disabled={this.state.busy} onClick={this.handleClick} />
)
}
}
如果我理解正确,当我单击按钮时,它将禁用它,呈现禁用的按钮,然后从api获取内容,然后设置结果的状态(并启用按钮),然后呈现启用的按钮。
这将防止人们单击该按钮10次,在第一次完成操作之前10次点击api。
我该如何使用功能组件和挂钩? 我天真的实现方式是这样,但似乎不正确。
MyButton = (props) => {
const [results, setResults] = useState([]);
const [errs, setErrs] = useState([]);
const [busy, setBusy] = useState(False);
const handleClick = () => {
setBusy(true);
fetchAPI().then(
(results) => {
setResults(results);
setErrs([]);
setBusy(False);
},
(err) => {
setErrs(errs);
setBusy(False);
});
);
}
return (
<Button disabled={busy} onClick={handleClick} />
)
}
有更好的方法吗?
答案 0 :(得分:0)
一种简单的方法是将fetchApi写入useEffect钩子中,并且您的按钮会在何时激活此效果之间进行切换,如下所示。您还可以签出react-query库来执行此操作
useEffect(()=>{
const loadApi = () => {
setBusy(true);
fetchAPI().then(
(results) => {
setResults(results);
setErrs([]);
setBusy(False);
},
(err) => {
setErrs(errs);
setBusy(False);
});
);
}
if (toggle) {
loadApi();
setToggle(false)
}
},[toggle])
const handleOnClick = () => {
setToggle(true)
}
答案 1 :(得分:0)
我认为您的实现没有任何问题。它应该工作。但是,如果您正在寻找更好的方法,可以考虑使用reducer和useReducer挂钩。
为所有状态定义一个化简器,包括错误,加载和加载状态。在加载状态下,将禁用设置为false。在加载状态下,您将禁用true。在fetchApi函数中,您可以调度各种操作。在调用API之前,请分派加载状态,然后在返回结果后,分配一个包含有效结果的加载状态。然后,您可以在组件中使用带有useReducer钩子的reducer,该钩子将为您提供状态和调度。使用state.disabled禁用按钮。
Helpful SO discussion around useReducer Good article on how to use useReducer for API calls