React使用useState存储Kakao图书接口数据为空无法渲染如何解决
问题原因分析
- useState更新是异步操作:调用
setBook(response.data.documents)后React不会立刻更新state变量,你在getBookList调用后立刻打印book,拿到的是当前渲染周期的旧值(初始空数组),并非更新后的值。 - 直接渲染对象报错:接口返回的
response.data.documents每个元素都是图书信息对象,React不支持直接把对象作为子元素渲染,所以直接写book[0]不会有正常输出,还会抛出运行时警告。 - 首次加载查询参数为空:
useEffect依赖为空数组,仅会在组件首次挂载时执行,此时title初始值是空字符串,首次调用接口返回的结果大概率为空。
修复方案
步骤1:验证state更新
新增监听book变化的useEffect,即可查看更新后的值:
useEffect(() => { console.log('book已更新:', book) }, [book])
步骤2:正确渲染数组内容
先做非空判断,再取出对象的具体字段渲染即可:
return ( <div> <input value={title} onChange={onChange}></input> <button onClick={getBookList}>push</button> {book.length > 0 ? ( <div> <p>书名:{book[0].title}</p> <p>作者:{book[0].authors.join(', ')}</p> <p>简介:{book[0].contents}</p> </div> ) : <p>暂无搜索结果</p>} </div> );
可选优化:补全接口请求头
Kakao开放接口需要在请求头中携带授权参数,否则会返回权限错误,补充对应配置即可:
const headers = { Authorization: 'KakaoAK 替换为你申请的Kakao REST API密钥' }
完整修复后代码
import { useState, useEffect } from 'react'; import axios from 'axios'; function Search(){ const [title, setTitle] = useState(''); const [book, setBook] = useState([]); const onChange = (e) => setTitle(e.target.value); const headers = { Authorization: 'KakaoAK 替换为你的Kakao开发者密钥' }; const getBookList = async () => { if(!title.trim()) return; try{ const response = await axios.get(`https://dapi.kakao.com/v3/search/book?target=title&query=${title}`, {headers}); setBook(response.data.documents); }catch(e){ console.log('接口请求错误:', e); } }; useEffect(()=>{ console.log('book更新后的值:', book); }, [book]); return ( <div> <input value={title} onChange={onChange} /> <button onClick={getBookList}>搜索</button> {book.length > 0 ? ( <div> <h3>第一本搜索结果:</h3> <p>书名:{book[0].title}</p> <p>作者:{book[0].authors?.join(', ') || '无'}</p> <p>出版社:{book[0].publisher}</p> </div> ) : <p>请输入关键词搜索图书</p>} </div> ); } export default Search;
内容的提问来源于stack exchange,提问作者sojinLee
相关产品推荐
相关产品推荐

