React中API获取数据无法在表格组件显示的问题求助
问题根源
你当前的实现存在核心逻辑错误:在Hero组件内部渲染的<Search data={data} />,和通过history('/search')跳转后路由匹配到的Search组件是完全独立的两个实例。当路由跳转后,Hero组件会被卸载,它内部的Search组件也随之销毁;新渲染的Search组件没有接收任何props,自然显示"No data available"。同时,组件内部的useState状态不会在路由跳转后保留,无法跨组件传递。
解决方案
以下是三种可行的修复方案,按实现复杂度和适用场景排序:
方案1:通过React Router的state传递数据
这是最简单的临时解决方案,适合快速验证逻辑:
修改Hero组件的handleSubmit函数
将跳转代码改为携带state数据:
axios.get(apiUrl) .then((response) => { console.log(response.data); // 携带数据跳转 history('/search', { state: { data: response.data } }); }) .catch((error) => { console.error('Error fetching data:', error); });
同时删除Hero组件return里的<Search data={data} />,因为路由跳转后不需要再渲染它。
修改Search组件
导入useLocation并获取传递的state:
import React from 'react' import Header from '../../components/Header/Header' import Footer from '../../components/Footer/Footer' import './Search.css' import { useLocation } from 'react-router-dom'; // 新增 const Search = () =>{ const location = useLocation(); // 从state中获取数据,默认空数组 const data = location.state?.data || []; return ( // 原渲染逻辑不变 ) } export default Search
方案2:将搜索参数带入URL,在Search组件重新请求API
这种方案更健壮,支持页面刷新后数据不丢失:
修改Hero组件的handleSubmit函数
跳转时将搜索参数拼接到URL:
axios.get(apiUrl) .then((response) => { console.log(response.data); // 直接跳转到带参数的search页面 history(`/search?${constructAPIUrl().split('?')[1]}`); }) .catch((error) => { console.error('Error fetching data:', error); });
同样删除Hero组件里的<Search data={data} />。
修改Search组件
使用useSearchParams获取URL参数,重新调用API:
import React, { useEffect, useState } from 'react' import Header from '../../components/Header/Header' import Footer from '../../components/Footer/Footer' import './Search.css' import { useSearchParams } from 'react-router-dom'; import axios from 'axios'; // 新增 const Search = () =>{ const [searchParams] = useSearchParams(); const [data, setData] = useState([]); useEffect(() => { // 从URL参数构造API地址 const baseUrl = 'http://74.208.39.34/search'; const apiUrl = `${baseUrl}?${searchParams.toString()}`; axios.get(apiUrl) .then((response) => { setData(response.data); }) .catch((error) => { console.error('Error fetching data:', error); }); }, [searchParams]); return ( // 原渲染逻辑不变 ) } export default Search
方案3:使用全局状态管理(Context API)
适合需要在多个组件共享搜索数据的场景:
1. 创建SearchContext
新建SearchContext.js文件:
import React, { createContext, useState, useContext } from 'react'; const SearchContext = createContext(); export const SearchProvider = ({ children }) => { const [searchData, setSearchData] = useState([]); return ( <SearchContext.Provider value={{ searchData, setSearchData }}> {children} </SearchContext.Provider> ); }; export const useSearchContext = () => useContext(SearchContext);
2. 在根组件包裹Provider
比如在App.js里:
import { SearchProvider } from './path/to/SearchContext'; import { BrowserRouter } from 'react-router-dom'; function App() { return ( <BrowserRouter> <SearchProvider> {/* 路由组件 */} </SearchProvider> </BrowserRouter> ); }
3. 修改Hero组件
使用Context保存数据:
import { useSearchContext } from '../path/to/SearchContext'; // 新增 const Hero = () => { const { setSearchData } = useSearchContext(); // 新增 // ...其他代码 const handleSubmit = (event) => { event.preventDefault(); const apiUrl = constructAPIUrl(); axios.get(apiUrl) .then((response) => { setSearchData(response.data); // 保存到全局状态 console.log(response.data); history('/search'); }) .catch((error) => { console.error('Error fetching data:', error); }); }; // 删除return里的<Search data={data} /> }
4. 修改Search组件
从Context获取数据:
import { useSearchContext } from '../path/to/SearchContext'; // 新增 const Search = () =>{ const { searchData } = useSearchContext(); const data = searchData || []; return ( // 原渲染逻辑不变 ) }
内容的提问来源于stack exchange,提问作者Henry Vjem
相关产品推荐
相关产品推荐

