React-query实现挂载时自动拉取,仅点击搜索按钮重新拉取数据
解决React Query + Next.js 搜索页手动触发查询的问题
需求场景
现有一个搜索结果页,需要将URL中的query参数传入useQuery发起数据请求。要求:
- 页面挂载时自动拉取一次初始搜索数据
- 用户修改搜索框内容后,仅在点击「搜索」按钮时才重新拉取数据
最初尝试的问题
曾尝试给useQuery设置enabled: false,然后在按钮点击时调用refetch(),但这样页面挂载时无法自动获取初始数据。不想用useEffect调用refetch(),认为这种方案不够合理。
最初示例代码
model.ts
const useSearch = (params) => { // 这里是使用params的业务逻辑 return useQuery<Type>(['/search' + params], {enabled: false}) }
view.tsx
const {query, push} = useRouter() const {data, refetch} = useSearch(query.search) const handleSearchParams = (v) => {push({query: {search: v}})} return( <> <Input onChange={handleSearchParams} value={query.search} /> <Button onClick={refetch}>Search</Button> </> )
最终实现方案
通过结合Next.js路由的isReady状态和本地状态管理,实现了需求,同时处理了Next.js初始渲染时query参数为undefined的特性:
const {query, push, isReady} = useRouter() const [value, setValue] = useState(query.search); const {data} = useSearch(query.search) useEffect(() => { if (!isReady) return; setValue(query.q); }, [isReady, query.q]); const handleChange = (e: ChangeEvent<HTMLInputElement>) => { setValue(e.target.value); }; const handleUpdateSearchQuery = () => { push({ query: { ...query, q: value } }); }; return( <> <Input onChange={handleChange} value={value} /> <Button onClick={handleUpdateSearchQuery}>Search</Button> </> )
方案说明
- 用本地状态
value管理搜索框的输入内容,避免输入时直接修改URL触发查询 - 点击「搜索」按钮时,通过
push更新URL的query参数,此时useSearch会因为传入的query.search变化自动触发新的查询 - 利用Next.js路由的
isReady状态,在路由准备完成后再将URL中的query参数同步到输入框的本地状态,解决初始渲染时query为undefined的问题
内容的提问来源于stack exchange,提问作者PCPbiscuit
相关产品推荐
相关产品推荐

