[英]Calling api manually in `useEffect()`
我对 function 组件的useEffect()
有疑问。
此脚本从服务器调用 api 并显示内容。
const NameList = (props) => {
const [result, setResult] = useState([]);
useEffect(() => {
var url = `http://localhost/blogs`;
axios.get(url)
.then((res)=> {
setResult(res.data.items);
})
.catch(err=>{console.log(err);});
}, []);
return(
<TableBody>
{
result.map(item => {
return (
<TableRow key={item.id}>
<TableCell>
{item.name}
</TableCell>
</TableRow>
)
})
}
</TableBody>
);
}
它在页面加载时显示列表(这很棒并且useEffect
很有用)。
我想通过手动调用 api 来刷新列表(例如,在另一个组件中单击按钮时等)
我有两个想法。
A)将ajax(axios.get)
保留在useEffect()
中并以某种方式从按钮调用useEffect()
。
B)在useEffect()
之外制作新的 function 包括ajax
并从 button 和useEffect()
调用它。
我可能仍然对如何使用useEffect()
。
我很欣赏哪一个是最佳实践的建议,我该如何做到这一点。
谢谢你。
创建一个新的 state 变量,例如。 刷新。
const [refresh, setRefresh] = useState(false);
每当您希望调用 useEffect 时更新刷新变量,例如在您的 onClick 处理程序内部
setRefresh(!refresh);
添加刷新到 useEffect 依赖数组,在最后一行使用效果
}, [refresh]);
现在 useEffect 像现在一样在第一次渲染时被调用,并且每次刷新 state 变量都会发生变化。
如果您之前使用过 class 组件,那么 useEffect 是生命周期方法的组合:componentDidMount()、componentDidUpdate() 和 componentWillUnmount()。 如果被跟踪的数组中没有任何被跟踪的状态,则 useEffect 仅在组件第一次挂载时触发,其效果与 componentDidMount() 相同。
所以选项B好,在外面定义function,第一次挂载的时候在useEffect中使用:
function getData() {
var url = `http://localhost/blogs`;
axios.get(url)
.then((res)=> {
setResult(res.data.items);
})
.catch(err=>{console.log(err);});
}
useEffect(() => {
getData()
},[])
然后使用单独的按钮触发 function:
<button onClick={getData}>Get Data</button
因此,如果您希望在重新加载时获取数据, useEffect已经处理好了,如果您要添加自定义按钮,建议有一个单独的 function 返回一个 promise,然后您可以轻松地将其放入useEffect function 等待它,也减少冗余,这样更有效率
...
// to get the data incase of conditions where we only need data and state change is not required
function functionName(){
return new Promise((resolve, reject)=>{
var url = `http://localhost/blogs`;
axios.get(url)
.then((res)=> {
resolve(res.data.items);
})
.catch(err=>{reject(err);});
})
}
// to handle the refresh button click,
// wire the function below to any button onClick so that refresh process will be done.
function manualRefreshOperation(){
functionName()
.then((res)=> {
setResult(res);
})
.catch(err=>{console.log(err);});
}
useEffect(() => {
manualRefreshOperation();
}, []);
此过程有助于减少冗余,并确保您可以将其链接到任何 function
您不能手动调用 useEffect。 Go with option B. Define the ajax call in a separate function and then call this function both in useEffect and in your button's onClick callback. 您唯一可以做的另一件事是,如果 state 在用户单击按钮时发生变化,那么您可以将该 state 变量放入 useEffect 的依赖数组中,因为它将在组件安装时调用,并且当 Z9ED39E2886A73A 变量发生变化时会调用它。
B) 在 useEffect() 之外创建新的 function 包括 ajax 并从按钮和 useEffect() 调用它。
这是一个好主意。 您可以将数据获取代码抽象为 function,您可以在效果和其他地方(例如在另一个事件处理程序中)调用它。
在这里,我将它附加到刷新按钮上的单击处理程序。
import { useState, useEffect } from "react";
import axios from "axios";
var url = `https://rickandmortyapi.com/api/character`;
const NameList = () => {
const [result, setResult] = useState([]);
const [loading, setloading] = useState(false);
const [error, seterror] = useState("");
const fetchData = () => {
setloading(true);
// get 3 random characters
const characters = [...Array(3)].map(() => (Math.random() * 183) | 0);
axios
.get(`${url}/${characters}`)
.then((res) => {
setResult(res.data);
seterror("");
})
.catch((err) => {
seterror(err.message);
})
.finally(() => {
setloading(false);
});
};
useEffect(() => {
fetchData();
}, []);
return (
<>
<button onClick={() => fetchData()}>refresh</button>
{error ? (
<p>{error}</p>
) : loading ? (
<p>"loading..."</p>
) : (
<table>
<tbody>
{result.map((item) => {
return (
<tr key={item.id}>
<td>{item.name}</td>
</tr>
);
})}
</tbody>
</table>
)}
</>
);
};
export default NameList;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.