React使用useState更新searchQuery状态后App组件未重新渲染问题
问题说明
你的App组件实际上已经正常触发重渲染了:你写的监听searchQuery的useEffect能输出最新值,就是App重渲染的直接证明。你看到的“更新后页面内容没变”,其实是子组件News没有响应searchQuery变化更新内容,以及setState的异步特性导致的误解。
核心问题点
- React的
setState是异步批量更新的,调用setSearchQuery后立刻打印searchQuery,拿到的还是本次渲染周期的旧值,属于正常现象,不需要修改 - 你使用
new String(searchText)给状态赋值,new String返回的是字符串包装对象,不是基础类型字符串,可能会导致后续全等判断出现异常 - News组件只在初始化时触发了一次新闻请求,没有监听传入的
searchQuery属性变化,所以即使App传了新的searchQuery,News也不会重新拉取数据刷新页面
修复方案
第一步:修正状态赋值逻辑
修改handelSearch方法,去掉不必要的new String包装,直接使用基础类型字符串赋值:
const handelSearch = (searchText) => { setSearchQuery(searchText); // 要打印新的搜索词直接用入参searchText即可,不需要读state console.log('Searching for : ', searchText); }
第二步:让News组件响应搜索词变化
二选一即可:
方案1:在News组件内添加监听逻辑(更推荐)
在News组件内部新增useEffect,监听searchQuery属性变化,变化时重新拉取新闻数据:
// News组件内部代码 useEffect(() => { // 调用你原本的新闻数据加载方法即可 loadNewsData(); }, [searchQuery, category]); // 把所有会影响新闻内容的props都加到依赖数组里
方案2:修改News组件的key,强制重建组件
如果不想改News组件的代码,可以直接给每个路由下的News组件的key加上searchQuery后缀,key变化时React会直接销毁旧组件渲染新组件,自动触发初始化加载逻辑:
// 举个例子,首页路由修改为如下格式,其他所有路由的News组件的key都按这个规则修改 <Route exact path="/"> <News key={`home-${searchQuery}`} setProgress={setProgress} pageSize={15} country="in" apiKey={API_KEY} searchQuery={searchQuery} category="general" /> </Route>
内容的提问来源于stack exchange,提问作者Anurag Goyar
相关产品推荐
相关产品推荐

