You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React应用中从详情页返回搜索页时保留历史搜索内容的问题咨询

问题原因

你的搜索关键词、结果都存在GoogleBooksSearch组件的内部state中,使用react-router跳转离开搜索页时,该组件会被卸载,内部state会被清空,再次返回页面时组件重新初始化,自然就没有之前的搜索内容了。

修复方案

这里推荐两种实现简单、兼容性好的方案,你可以根据需求选择:

方案1:URL参数存储(推荐,支持刷新页面也保留内容)

将搜索关键词存在页面URL的query参数中,每次组件挂载时优先读取URL参数初始化内容,跳转页面后URL参数不会丢失,返回时直接读取即可,还支持分享搜索结果链接。

改动代码(以react-router v6为例):

  1. 先给输入框绑定value属性,修正受控组件的写法
  2. 引入useSearchParams读取和修改URL参数
  3. 组件挂载时自动根据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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 07:15:03