React Gatsby搜索框更新时如何触发API重渲染更新组件
Gatsby React 搜索功能不生效修复
问题根因
当前代码存在核心问题导致搜索无法触发更新:
- 数据请求的
useEffect依赖数组为空[],仅会在组件首次挂载时执行1次,后续输入框更新search状态时,不会触发接口重新请求 - 请求头
myHeaders定义在组件顶层作用域,每次组件重渲染都会重新创建,且多次调用getPeople时会重复往headers里追加相同字段,累积后容易触发请求异常 - 无防抖、无请求取消逻辑时,输入过程会高频发送请求,还容易出现请求竞态,导致最终展示结果和输入内容不匹配
修复步骤
- 将
search加入useEffect的依赖项,移除不必要的eslint禁用注释 - 把
Headers实例初始化逻辑移到getPeople函数内部,每次请求生成新的headers实例,避免字段重复追加 - 增加输入防抖、请求取消逻辑,优化使用体验、避免结果错乱
- 给输入框绑定
value属性改为标准受控组件,避免输入值和状态不同步 - 拼接搜索参数时用
encodeURIComponent处理特殊字符,避免请求参数格式错误
修复后完整代码
import React, { useState, useEffect, Fragment } from 'react' const PeoplePage = () => { const [search, setSearch] = useState("") const [people, setPeople] = useState() const getPeople = async (controller) => { // 每次请求新建headers实例,避免重复追加字段 const myHeaders = new Headers(); myHeaders.append("Access-Control-Request-Headers", process.env.GATSBY_PEOPLE_ACCESS_CONTROL); myHeaders.append("Authorization", process.env.GATSBY_PEOPLE_BEARER); const requestOptions = { method: 'GET', headers: myHeaders, redirect: 'follow', signal: controller.signal // 绑定取消信号,处理竞态问题 }; try { const response = await fetch( `${process.env.GATSBY_PEOPLE_API}&search=${encodeURIComponent(search)}`, requestOptions ); const result = await response.json(); setPeople(result) } catch (err) { // 忽略主动取消请求抛出的正常错误 if (err.name !== 'AbortError') console.error(err); } }; const searchUpdate = (e) => { setSearch(e.target.value) } useEffect(() => { // 500ms防抖,避免输入过程中高频发送请求 const timer = setTimeout(() => { const controller = new AbortController() getPeople(controller) // 搜索词变化、组件卸载时取消未完成的请求 return () => controller.abort() }, 500) return () => clearTimeout(timer) }, [search]) // 把search加入依赖,搜索词变化时自动触发请求 return ( <Fragment> <input placeholder="Search.." onChange={searchUpdate} value={search} /> <div className="people"> {people ? Object.values(people).map(person => { return ( <div id={"person-"+person.id} key={person.id} > {person.name} </div> ) }) : "Not available.."} </div> </Fragment > ) } export default PeoplePage
内容的提问来源于stack exchange,提问作者iamaprogrammer
相关产品推荐
相关产品推荐

