React触发OnClick事件后控制台有数据但页面不渲染
问题根因
你的代码存在3个核心问题,导致接口返回数据后页面无法正常渲染:
- 状态更新时序错误:
setIsLoading(false)写在了axios.get()异步请求的同步执行区,请求刚发起就会立刻把加载状态设为false,完全等不到接口返回。
- 状态更新时序错误:
- 数据读取路径不匹配:初始state定义的结构是
{data: []},但你直接执行setData(response.data)时,如果接口返回的数组本身就是response.data(没有嵌套一层data字段),那渲染时写的data.data?.map()会取到undefined,根本不会执行列表渲染。
- 数据读取路径不匹配:初始state定义的结构是
- 存在无效冗余代码:
const {data} = axios.get(URL, config)是同步写法,axios.get返回的是Promise对象,这行永远拿不到接口返回数据,属于无效代码。
- 存在无效冗余代码:
- 额外问题:全链路没有错误捕获,拿token失败、拉数据失败时用户看不到任何提示。
修复后的完整代码
import {useState} from 'react'; import axios from 'axios'; import '../App.css' // 登录参数 const loginParams = { username: "xyz", password: "xyz" }; const type_no = '88'; const URL = `example url://abc.com/abc/${type_no}`; // 获取token方法 async function getToken(){ const res = await axios.post("example url://abc.com/", loginParams) return res.data.IdToken }; const App = () => { // 列表初始值设为数组,避免嵌套取值混乱 const [list, setList] = useState([]); const [isLoading, setIsLoading] = useState(false); const [err, setErr] = useState(''); const handleClick = async () => { // 重置状态 setErr('') setIsLoading(true); try { // 同步等待获取token const token = await getToken(); const config = { headers: { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json', } }; // 拉取列表数据 const res = await axios.get(URL, config) console.log('接口返回数据:', res); // 重点:根据接口实际返回结构取值,列表直接在res.data就传res.data,在res.data.data下就传res.data.data setList(res.data) } catch (error) { console.error('请求失败:', error); setErr('数据加载失败,请重试') } finally { // 不管请求成功/失败,最后统一关闭加载态 setIsLoading(false) } }; return ( <div className="form"> {err && <h2>{err}</h2>} <button onClick={handleClick} disabled={isLoading}>Show the data</button> {isLoading && <h2>Loading data...</h2>} { list.map(item => { return ( <div key={item.id}> <h2>{item.email}</h2> <h2>{item.first_name}</h2> <h2>{item.last_name}</h2> <br /> </div> ); }) } </div> ); }; export default App;
关键调整说明
- 把嵌套的then链改成async/await写法,避免异步时序混乱,
isLoading的关闭放到finally逻辑里,保证请求结束一定会正确更新加载状态。 - 把原来容易混淆的
data状态名改成list,避免和接口返回的data字段、map回调参数重名导致的取值错误。 - 补全了全链路的错误捕获,请求失败时会在页面展示错误提示。
- 加载过程中给按钮加了disabled状态,防止用户重复点击触发重复请求。
- 删掉了无效的同步解构Promise的冗余代码。
内容的提问来源于stack exchange,提问作者user19478298
相关产品推荐
相关产品推荐

