React中如何避免用户提交输入前调用API加载数据?
问题根源
- 未提交就发起请求:你当前的
useEffect依赖数组为空,会在组件首次挂载完成后立刻执行,此时owner还是初始的空字符串,所以会发起无效的API请求 - 依赖警告:
useEffect内部用到了响应式状态owner,但没有将其加入依赖数组,违反了React Hook的依赖检查规则,所以会触发警告
修复方案
有两种可行的实现方式,推荐优先用第一种,逻辑更直接无冗余:
方案1:将请求逻辑放到提交事件中(最优)
完全不需要用到useEffect,只有用户点击提交按钮的时候才会发起请求,从根源避免自动触发的无效请求,修正后的完整代码如下:
import { useState } from "react"; // example user input: 0x147412d494731cbb91dbb5d7019464a536de04dc function App() { const [data, setData] = useState({ assets: [] }); const [enteredWallet, setEnteredWallet] = useState(""); // 这里owner状态如果没有其他用处可以直接删掉,直接用enteredWallet即可 const [owner, setOwner] = useState(""); const walletChangeHandler = (event) => { setEnteredWallet(event.target.value); }; const submittedHandler = async (event) => { event.preventDefault(); setOwner(enteredWallet); // 直接在提交时发起请求 const res = await fetch( `https://api.opensea.io/api/v1/assets?owner=${enteredWallet}&order_direction=desc&offset=0&limit=10` ); const resData = await res.json(); setData(resData); }; return ( <div className="App"> <header className="App-header"> <h3>Show me assets in this wallet</h3> <form onSubmit={submittedHandler}> <input placeholder="wallet address" value={enteredWallet} onChange={walletChangeHandler} /> <button>Submit</button> </form> <div> {data.assets.map((i, index) => ( <li key={index}>{i.name}</li> ))} </div> </header> </div> ); } export default App;
方案2:调整useEffect逻辑
如果你需要保留useEffect的写法,只需要做两处修改:
- 将
owner加入useEffect的依赖数组,解决依赖警告 - 增加非空判断,只有
owner有有效值的时候才发起请求
修正后的useEffect代码如下:
useEffect(() => { // 初始owner为空,直接跳过不发请求 if (!owner) return; fetch( `https://api.opensea.io/api/v1/assets?owner=${owner}&order_direction=desc&offset=0&limit=10` ) .then((res) => res.json()) .then((data) => setData(data)); }, [owner]);
关于初始状态的说明
owner的初始状态会直接影响请求逻辑:如果初始值为''/null/undefined这类假值,只要加上非空判断就不会触发无效请求;如果初始值不小心填了一个默认地址,就会在组件挂载时自动发起对应地址的请求,不符合你的需求。
内容的提问来源于stack exchange,提问作者somniumm
相关产品推荐
相关产品推荐

