Reactjs 使用React钩子强制触发异步请求
我无法决定如何强制触发API调用,例如,在单击按钮时。Reactjs 使用React钩子强制触发异步请求,reactjs,react-hooks,Reactjs,React Hooks,我无法决定如何强制触发API调用,例如,在单击按钮时。 我不确定使用钩子的正确方法是什么,因为似乎不止一种方法,但我不知道哪种方法是“最好的”方法以及最终的含义 我发现以下示例非常简单,可以做我想做的事情: 将useEffect()与触发器值一起使用 函数SomeFunctionComponent(){ const[fakeData,setFakeData]=useState(0); const[trigger,setTrigger]=useState(false); 异步函数fetchData
我不确定使用钩子的正确方法是什么,因为似乎不止一种方法,但我不知道哪种方法是“最好的”方法以及最终的含义 我发现以下示例非常简单,可以做我想做的事情: 将useEffect()与触发器值一起使用
函数SomeFunctionComponent(){
const[fakeData,setFakeData]=useState(0);
const[trigger,setTrigger]=useState(false);
异步函数fetchData(){
如果(!触发器)返回;
const newData=等待someAPI.fetch();
设置触发器(假);
setFakeData(新数据);
}
useffect(()=>{
fetchData();
},[触发];
返回(
{fakeData}
setTrigger(!trigger)}>刷新
);
}
只需调用API,然后调用setState()
函数SomeFunctionComponent(){
const[fakeData,setFakeData]=useState(0);
异步函数fetchData(){
const newData=等待someAPI.fetch();
setFakeData(新数据);
}
返回(
{fakeData}
刷新
);
}
还有其他一些方法可以利用useCallback(),但据我所知,它们对于在向下传递回调时避免重新呈现子组件非常有用,与第二个示例相当
我认为useEffect方法只有在必须以编程方式在组件挂载上运行时才有用,但本质上是一个伪值来触发副作用看起来很冗长。仅仅调用函数看起来非常实用和简单,但我不确定是否允许函数组件在渲染期间执行副作用
在React中使用hooks进行命令式调用,哪种方法最惯用、最正确?当我试图找出写东西的最佳方法时,我要做的第一件事就是看看我想如何使用它。在您的情况下,此代码:
<React.Fragment>
<p>{fakeData}</p>
<button onClick={fetchData}>Refresh</button>
</React.Fragment>
被接受的答案实际上打破了这一界限。由于单击是异步的,这意味着在fetch调用期间可能会发生其他渲染,这将产生副作用,可能会产生可怕的效果 我们可以通过在调用
setState()
函数之前检查组件是否已装入来修复它。下面是我的解决方案,它相当容易使用
挂钩功能
函数useApi(actionAsync,initialResult){
常量[loading,setLoading]=React.useState(false);
const[result,setResult]=React.useState(initialResult);
const[fetchFlag,setFetchFlag]=React.useState(0);
React.useffect(()=>{
如果(fetchFlag==0){
//仅在调用triggerFetch后运行
返回;
}
让我们假设这是真的;
设置加载(真);
actionAsync()。然后(res=>{
如果(已安装){
//仅当组件仍然安装时才修改状态
设置加载(假);
设置结果(res);
}
})
//表示compnoent已“清理”的信号
返回()=>mounted=false;
},[fetchFlag])
函数triggerFetch(){
//设置fetchFlag以间接触发上述useEffect
setFetchFlag(Math.random());
}
返回[结果、triggerFetch、加载];
}
在React hook中的用法
函数MyComponent(){
异步函数fetchUsers(){
const data=wait fetch(“myapi”)。然后((r)=>r.json();
返回数据;
}
const[fetchResult,fetchTrigger,fetchLoading]=useApi(fetchUsers,null);
返回(
刷新用户
{fetchLoading?“正在加载”:“完成”}
{JSON.stringify(fetchResult)}
);
}
如果您只想在单击按钮时运行效果,那么仅仅为了运行效果而引入一段状态会让您觉得浪费。如果您想在道具发生变化时再次提取数据,那么使用效果是有意义的,但在这种情况下,您也可以在事件处理程序中提取数据。如果您想在装载时加载效果(第二个选项),只需使用useffect
调用useffect
中的fetchData
函数,以确保只运行一次。我想,像往常一样,简单和直接的事情是最好的。我认为功能组件中的所有副作用都必须在useEffect中执行?为什么这里不是这样?谢谢,这不是副作用。这是一个用户生成的动作onClick@AlonBarDavid用户生成的操作实际上是一种副作用,对吗?如果SomeFunctionComponent
在调用setData()
之前被销毁,那么它将抛出一个错误。对于提供的每个实现,如果我们在销毁组件之后使用setData,则会发生错误。这与副作用无关,您必须在某个时候影响组件状态才能重新提交新数据。为了防止这种情况,正确的方法是在使用useEffect的返回调用销毁组件时取消api请求。虽然在库代码之外,但很少这样做,因为它需要大量的样板文件,我们通常可以假设它不会发生,或者我们不在乎如果发生了警告。