React应用中从详情页返回搜索页时保留历史搜索内容的问题咨询
问题原因
你的搜索关键词、结果都存在GoogleBooksSearch组件的内部state中,使用react-router跳转离开搜索页时,该组件会被卸载,内部state会被清空,再次返回页面时组件重新初始化,自然就没有之前的搜索内容了。
修复方案
这里推荐两种实现简单、兼容性好的方案,你可以根据需求选择:
方案1:URL参数存储(推荐,支持刷新页面也保留内容)
将搜索关键词存在页面URL的query参数中,每次组件挂载时优先读取URL参数初始化内容,跳转页面后URL参数不会丢失,返回时直接读取即可,还支持分享搜索结果链接。
改动代码(以react-router v6为例):
- 先给输入框绑定
value属性,修正受控组件的写法 - 引入
useSearchParams读取和修改URL参数 - 组件挂载时自动根据URL参数回填搜索词、加载搜索结果
import { useState, useEffect } from 'react'; import { useSearchParams } from 'react-router-dom'; import axios from 'axios'; function GoogleBooksSearch() { const [searchParams, setSearchParams] = useSearchParams(); // 初始化时优先读取URL里的搜索词 const [book, setBook] = useState(searchParams.get('q') || ""); const [result, setResult] = useState([]); const apiKey = "MY API" function handleChange(event) { const book = event.target.value; setBook(book); } function handleSubmit(event) { event.preventDefault(); // 提交搜索时把搜索词写入URL参数 setSearchParams({ q: book }); axios.get("https://www.googleapis.com/books/v1/volumes?q=" + book + "&key=" + apiKey + "&maxResults=20") .then(data => { setResult(data.data.items); }) } // 组件挂载/URL参数变化时,自动加载对应搜索结果 useEffect(() => { const q = searchParams.get('q'); if(q && !result.length) { axios.get("https://www.googleapis.com/books/v1/volumes?q=" + q + "&key=" + apiKey + "&maxResults=20") .then(data => { setResult(data.data.items); }) } }, [searchParams, apiKey, result.length]); return ( <div> <div className="hero-container"> <h1>Search your book</h1> <p>Discover the best books ever</p> <form onSubmit={handleSubmit}> <div className='container'> <div> {/* 这里新增value属性绑定state */} <input value={book} onChange={handleChange} className="form" autoFocus placeholder="Enter the title of the book" type="text" /> <div style={{ marginTop: '20px' }}></div> <div className='d-grid gap-2 '> <input type="submit" value="SEARCH" className="btn btn-primary btn-lg mx-auto" /> </div> </div> </div> </form> </div> {/* 原有搜索结果渲染逻辑不变 */} </div> ) }
方案2:本地存储实现
如果不需要支持分享搜索链接,也可以把搜索词和结果存在sessionStorage中,关闭页面后自动清除,不会永久占用存储空间:
// 组件初始化时读取本地存储内容 const [book, setBook] = useState(sessionStorage.getItem('searchKeyword') || ""); const [result, setResult] = useState(JSON.parse(sessionStorage.getItem('searchResult') || '[]')); // 提交搜索时把内容写入本地存储 function handleSubmit(event) { event.preventDefault(); sessionStorage.setItem('searchKeyword', book); axios.get("https://www.googleapis.com/books/v1/volumes?q=" + book + "&key=" + apiKey + "&maxResults=20") .then(data => { sessionStorage.setItem('searchResult', JSON.stringify(data.data.items)); setResult(data.data.items); }) }
内容的提问来源于stack exchange,提问作者EmmE
相关产品推荐
相关产品推荐

