如何在 Effect Hook 中使用 axios?
Posted
技术标签:
【中文标题】如何在 Effect Hook 中使用 axios?【英文标题】:How to use axios in Effect Hook? 【发布时间】:2019-04-08 18:47:17 【问题描述】:在基于类的组件中:
componentDidMount()
axios.get('https://jsonplaceholder.typicode.com/posts').then((res) =>
this.setState(
posts: res.data.slice(0, 10)
);
console.log(posts);
)
我试过这个:
const [posts, setPosts] = useState([]);
useEffect(() =>
axios.get('https://jsonplaceholder.typicode.com/posts').then((res) =>
setPosts(res.data.slice(0, 10));
console.log(posts);
)
);
它创建了一个无限循环。如果我将 []/ 作为第二个参数 [1][2] 传递,那么它会阻止进一步的调用。但它也阻止了数组更新。
[1]Infinite loop in useEffect
[2]How to call loading function with React useEffect only once
【问题讨论】:
“如果我将[]
/
作为第二个参数传递,那么它会阻止进一步调用”是什么意思。这就是你想要做的,只在初始渲染后运行给useEffect
的函数。
是的。我想运行一次该函数,因为它一次又一次地更新帖子数组。遵循您在其他帖子中提到的方法后,我得到了预期的“运行 useEffect 一次”,但我的帖子数组仍然是空的。不应该是 [post1, post2, ...]。
It should work to give an empty array as the second argument.
谢谢。 codesandbox.io/s/w0xx6zl5wk?module=%2Fsrc%2FHome.js
@Tholle 我接受了你的回答。
【参考方案1】:
给useEffect
提供一个空数组作为第二个参数,以表明您只希望效果在初始渲染后运行一次是可行的方法。 console.log(posts);
向您显示一个空数组的原因是因为 posts
变量仍然引用初始数组,而 setPosts
也是异步的,但如果在渲染中使用它仍然可以按您的意愿工作。
示例
const useState, useEffect = React;
function App()
const [posts, setPosts] = useState([]);
useEffect(() =>
setTimeout(() =>
setPosts([ id: 0, content: "foo" , id: 1, content: "bar" ]);
console.log(posts);
, 1000);
, []);
return (
<div>posts.map(post => <div key=post.id>post.content</div>)</div>
);
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>
【讨论】:
【参考方案2】:您可以查看axios-hooks 是如何实现的。
它超级简单,使用您提供的配置对象(或 url)来决定何时发出请求,何时不发出请求,如 Tholle's answer 中所述。
除了允许您在无状态功能组件中使用出色的 axios 之外,它还支持服务器端渲染,事实证明,钩子可以非常简单地实现。
免责声明:我是该软件包的作者。
【讨论】:
这个包太棒了!虽然我想知道第一次调用 useAxios 时如何不发送请求?因为在提交表单之前你永远不会发布任何东西。 @Min 目前不支持它,但希望它很容易实现。你会在项目 github 页面上创建一个问题吗?也欢迎 PR :)【参考方案3】:我为 Axios.js 写了一个Custom Hooks。
这是一个例子:
import React, useState from 'react';
import useAxios from '@use-hooks/axios';
export default function App()
const [gender, setGender] = useState('');
const
response,
loading,
error,
query,
= useAxios(
url: `https://randomuser.me/api/$gender === 'unknow' ? 'unknow' : ''`,
method: 'GET',
options:
params: gender ,
,
trigger: gender,
filter: () => !!gender,
);
const data = response || ;
const options = [
gender: 'female', title: 'Female' ,
gender: 'male', title: 'Male' ,
gender: 'unknow', title: 'Unknow' ,
];
if (loading) return 'loading...';
return (
<div>
<h2>DEMO of <span style= color: '#F44336' >@use-hooks/axios</span></h2>
options.map(item => (
<div key=item.gender>
<input
type="radio"
id=item.gender
value=item.gender
checked=gender === item.gender
onChange=e => setGender(e.target.value)
/>
item.title
</div>
))
<button type="button" onClick=query>Refresh</button>
<div>
error ? error.message || 'error' : (
<textarea cols="100" rows="30" defaultValue=JSON.stringify(data || , '', 2) />
)
</div>
</div>
);
你可以看到结果online。
【讨论】:
以上是关于如何在 Effect Hook 中使用 axios?的主要内容,如果未能解决你的问题,请参考以下文章
react-hook-form axios post - 无法创建有效负载