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

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

2024-06-30 17:40  views:247  source:许某    

使用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>
);
}



Disclaimer: The above articles are added by users themselves and are only for typing and communication purposes. They do not represent the views of this website, and this website does not assume any legal responsibility. This statement is hereby made! If there is any infringement of your rights, please contact us promptly to delete it.

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