首页 练字文章 使用async await 时的报错,useEffect响应更新

使用async await 时的报错,useEffect响应更新

2024-06-30 17:40  浏览数:24  来源:许某    

使用async await 时的报错
在代码中,我们使用async / await从第三方API获取数据。
如果你对async/await熟悉的话,你会知道,每个async函数都会默认返回一个隐式的promise。
但是,useEffect不应该返回任何内容。这就是为什么会在控制台日志中看到以下警告:
Warning: useEffect function must
return a cleanup function or nothing.
Promises and useEffect(async () => …)
are not supported, but you can call an
async function inside an effect
这就是为什么不能直接在useEffect中使用async函数,
因此,我们可以不直接调用async函数,而是像下面这样:
function App() {
const [data, setData] = useState({ hits: [] });
useEffect(() => {
const fetchData = async () => {
const result = await axios(
'urladdress?query=redux',
);
setData(result.data);
};
fetchData();
}, []);
return (
<ul>
{data.hits.map(item => (
<li key={item.objectID}>
<a href={item.url}>{item.title}</a>
</li>
))}
</ul>
);
}
4.useEffect在实战中的应用
4.1 响应更新
很多情况下,我们需要响应用户的输入,然后再请求。这个时候我们会引入一个input框,监听query值的变化:
import axios from 'axios';
function App() {
const [data, setData] = useState({ hits: [] });
const [query, setQuery] = useState('redux');
useEffect(() => {
const fetchData = async () => {
const result = await axios(
'urladdress?query=redux',
);
setData(result.data);
};
fetchData();
}, []);
return (
<Fragment>
<input
type="text"
value={query}
onChange={event =>
setQuery(event.target.value)}
/>
<ul>
{data.hits.map(item => (
<li key={item.objectID}>
<a href={item.url}>{item.title}</a>
</li>
))}
</ul>
</Fragment>
);
}
有个query值,已经更新query的逻辑,
还需要将这个query值传递给后台,这个操作会在useEffect中进行
前面我们说了,目前的useEffect只会在组件mount时执行,
并且useEffect的第二个参数是依赖的变量,一旦这个依赖的变量变动,
useEffect就会重新执行,所以我们需要添加query为useEffect的依赖:
function App() {
const [data, setData] = useState({ hits: [] });
const [query, setQuery] = useState('redux');
useEffect(() => {
const fetchData = async () => {
const result = await axios(
`urladdress=${query}`,
);
setData(result.data);
};
fetchData();
}, [query]);
return (
...
);
}
一旦更改了query值,就可以重新获取数据。但这会带来另一个问题:
query的任何一次变动都会请求后端,这样会带来比较大的访问压力。
这个时候我们需要引入一个按钮,点击这个按钮再发起请求。
function App() {
const [data, setData] = useState({ hits: [] });
const [query, setQuery] = useState('redux');
const [search, setSearch] = useState('');
useEffect(() => {
const fetchData = async () => {
const result = await axios(
`urladdress?query=${query}`,
);
setData(result.data);
};
fetchData();
}, [query]);
return (
<Fragment>
<input
type="text"
value={query}
onChange={event => setQuery(event.target.value)}
/>
<button type="button"
onClick={() => setSearch(query)}>
Search
</button>
<ul>
{data.hits.map(item => (
<li key={item.objectID}>
<a href={item.url}>{item.title}</a>
</li>
))}
</ul>
</Fragment>
);
}
可以看到上面我们添加了一个新的按钮,然后创建新的组件state:search。
每次点击按钮时,会把search的值设置为query,
这个时候我们需要修改useEffect中的依赖项为search,
这样每次点击按钮,search值变更,useEffect就会重新执行,避免不必要的变更:
function App() {
const [data, setData] = useState({ hits: [] });
const [query, setQuery] = useState('redux');
const [search, setSearch] = useState('redux');
useEffect(() => {
const fetchData = async () => {
const result = await axios(
`urladdress?query=${search}`,
);
setData(result.data);
};
fetchData();
}, [search]);
return (
...
);
}
export default App;
此外,search state的初始状态设置为与query state 相同的状态,
因为组件首先会在mount时获取数据。所以简单点,
直接将的要请求的后端URL设置为search state的初始值。
function App() {
const [data, setData] = useState({ hits: [] });
const [query, setQuery] = useState('redux');
const [url, setUrl] = useState(
'urladdress?query=redux',
);
useEffect(() => {
const fetchData = async () => {
const result = await axios(url);
setData(result.data);
};
fetchData();
}, [url]);
return (
<Fragment>
<input
type="text"
value={query}
onChange={event =>
setQuery(event.target.value)}
/>
<button
type="button"
onClick={() =>
setUrl(`urladdress?query=${query}`)
}
>
Search
</button>
<ul>
{data.hits.map(item => (
<li key={item.objectID}>
<a href={item.url}>{item.title}</a>
</li>
))}
</ul>
</Fragment>
);
}



声明:以上文章均为用户自行添加,仅供打字交流使用,不代表本站观点,本站不承担任何法律责任,特此声明!如果有侵犯到您的权利,请及时联系我们删除。

字符:    改为:
去打字就可以设置个性皮肤啦!(O ^ ~ ^ O)