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

如何在SolidJS中实现搜索图书信息跨页面/组件展示?

解决SolidJS中搜索图书后跨页面展示数据的问题

首先修正你代码中的核心数据存储错误:你当前用setBook(response.data)存储的是API返回的完整对象,但实际需要的图书列表是response.data.items数组。修改handleSubmit中的这一行:

setBook(response.data.items || []); // 存储图书数组,同时处理无搜索结果的情况

以下是三种可行的解决方案,根据你的页面结构选择:

方案1:Props传递(组件嵌套场景)

如果Books是SearchBooks的子组件,直接通过props传递数据:

修改SearchBooks的return部分,添加Books组件并传入数据:

return (
  <div className="w-full mt-10 bg-gray-100 flex justify-center items-center">
    <div className="container mx-auto dark:bg-gray-900 rounded-lg p-14">
      <form onSubmit={handleSubmit}>
        {/* 现有表单代码 */}
      </form>
      {/* 传入图书数据给Books组件 */}
      <Books books={book()} />
    </div>
  </div>
);

在Books.jsx中接收并渲染数据:

function Books(props) {
  return (
    <div className="mt-8">
      <h2 className="text-2xl font-bold text-white mb-4">搜索结果</h2>
      {props.books.length === 0 ? (
        <p className="text-white">暂无图书数据</p>
      ) : (
        props.books.map(book => (
          <div key={book.id} className="bg-white rounded-lg p-4 mb-4">
            <h3 className="text-xl font-semibold">{book.volumeInfo.title}</h3>
            {book.volumeInfo.authors && (
              <p className="text-gray-600">作者:{book.volumeInfo.authors.join(', ')}</p>
            )}
            {book.volumeInfo.categories && (
              <p className="text-gray-600">类型:{book.volumeInfo.categories.join(', ')}</p>
            )}
            <p className="text-gray-600">可用性:{book.accessInfo.embeddable ? "可在线查看" : "不可在线查看"}</p>
            {book.volumeInfo.description && (
              <p className="mt-2 text-gray-700">{book.volumeInfo.description}</p>
            )}
          </div>
        ))
      )}
    </div>
  );
}

export default Books;

方案2:Solid Router导航传参(独立页面跳转场景)

如果需要跳转到全新页面展示结果,用路由状态传递数据:

  1. 根组件配置路由:
import { Router, Routes, Route } from "@solidjs/router";
import SearchBooks from "./SearchBooks";
import BookList from "./BookList";

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" component={SearchBooks} />
        <Route path="/book-list" component={BookList} />
      </Routes>
    </Router>
  );
}
  1. 修改SearchBooks,添加导航逻辑:
import axios from "axios";
import { createSignal } from "solid-js";
import { useNavigate } from "@solidjs/router";

function SearchBooks() {
  const [searchText, setSearchText] = createSignal("");
  const navigate = useNavigate();

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      const response = await axios.get(
        `https://www.googleapis.com/books/v1/volumes?q=${searchText()}`
      );
      const books = response.data.items || [];
      // 跳转并携带数据
      navigate("/book-list", { state: { books } });
    } catch (error) {
      console.log(error);
    }
  };

  // 现有return代码不变
}

export default SearchBooks;
  1. 在BookList.jsx中获取并渲染数据:
import { useLocation } from "@solidjs/router";

function BookList() {
  const location = useLocation();
  const books = location.state?.books || [];

  return (
    <div className="container mx-auto mt-10 p-4">
      <h2 className="text-3xl font-bold mb-6">图书搜索结果</h2>
      {books.length === 0 ? (
        <p>暂无搜索结果</p>
      ) : (
        books.map(book => (
          <div key={book.id} className="border rounded-lg p-4 mb-4">
            <h3 className="text-xl font-semibold">{book.volumeInfo.title}</h3>
            <p className="text-gray-600">作者:{book.volumeInfo.authors?.join(', ') || '未知'}</p>
            <p className="text-gray-600">类型:{book.volumeInfo.categories?.join(', ') || '未分类'}</p>
            <p className="text-gray-600">可用性:{book.accessInfo.embeddable ? "可在线查看" : "不可在线查看"}</p>
            {book.volumeInfo.description && (
              <p className="mt-2 text-gray-700 line-clamp-3">{book.volumeInfo.description}</p>
            )}
          </div>
        ))
      )}
    </div>
  );
}

export default BookList;

方案3:全局状态管理(多组件共享数据场景)

如果需要在多个页面共享图书数据,用createContext实现全局状态:

  1. 创建BookContext.jsx:
import { createContext, useContext, createSignal } from "solid-js";

const BookContext = createContext();

export function BookProvider({ children }) {
  const [books, setBooks] = createSignal([]);

  return (
    <BookContext.Provider value={{ books, setBooks }}>
      {children}
    </BookContext.Provider>
  );
}

export function useBookContext() {
  return useContext(BookContext);
}
  1. 根组件包裹全局状态:
import { Router, Routes, Route } from "@solidjs/router";
import { BookProvider } from "./BookContext";
import SearchBooks from "./SearchBooks";
import BookList from "./BookList";

function App() {
  return (
    <BookProvider>
      <Router>
        <Routes>
          <Route path="/" component={SearchBooks} />
          <Route path="/book-list" component={BookList} />
        </Routes>
      </Router>
    </BookProvider>
  );
}
  1. 修改SearchBooks更新全局状态:
import axios from "axios";
import { createSignal } from "solid-js";
import { useNavigate } from "@solidjs/router";
import { useBookContext } from "./BookContext";

function SearchBooks() {
  const [searchText, setSearchText] = createSignal("");
  const navigate = useNavigate();
  const { setBooks } = useBookContext();

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      const response = await axios.get(
        `https://www.googleapis.com/books/v1/volumes?q=${searchText()}`
      );
      const books = response.data.items || [];
      setBooks(books);
      navigate("/book-list");
    } catch (error) {
      console.log(error);
    }
  };

  // 现有return代码不变
}

export default SearchBooks;
  1. 在BookList.jsx读取全局状态:
import { useBookContext } from "./BookContext";

function BookList() {
  const { books } = useBookContext();

  return (
    <div className="container mx-auto mt-10 p-4">
      <h2 className="text-3xl font-bold mb-6">图书搜索结果</h2>
      {books().length === 0 ? (
        <p>暂无搜索结果</p>
      ) : (
        books().map(book => (
          <div key={book.id} className="border rounded-lg p-4 mb-4">
            <h3 className="text-xl font-semibold">{book.volumeInfo.title}</h3>
            <p className="text-gray-600">作者:{book.volumeInfo.authors?.join(', ') || '未知'}</p>
            <p className="text-gray-600">类型:{book.volumeInfo.categories?.join(', ') || '未分类'}</p>
            <p className="text-gray-600">可用性:{book.accessInfo.embeddable ? "可在线查看" : "不可在线查看"}</p>
            {book.volumeInfo.description && (
              <p className="mt-2 text-gray-700 line-clamp-3">{book.volumeInfo.description}</p>
            )}
          </div>
        ))
      )}
    </div>
  );
}

export default BookList;

内容的提问来源于stack exchange,提问作者Hjaeter

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:17:56