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

React Router中无需高阶函数实现组件间数据共享及路由渲染问题

解决方法

有两种常用方案可以满足你的需求:

方案1:将上下文提供者抽离为独立组件(推荐)

把上下文的状态管理和UI组件拆分开,让Provider独立包裹所有需要访问上下文的路由,这样不管是/flights还是/flights/flight-results都能拿到上下文数据,且各自只渲染对应组件。

步骤:

  1. 创建独立的上下文提供者组件
// FlightSearchProvider.tsx
import { createContext, useContext, useState } from 'react';

// 定义上下文
const FlightSearchContext = createContext(null);

export const FlightSearchProvider = ({ children }) => {
  // 在这里定义原来Flights组件里的所有状态(比如typeOfTrip、fromAirport等)
  const [typeOfTrip, setTypeOfTrip] = useState('one-way');
  const [fromAirport, setFromAirport] = useState('');
  const [departureDate, setDepartureDate] = useState('');
  const [returnDate, setReturnDate] = useState('');
  const [toAirport, setToAirport] = useState('');
  const [outGoingFlights, setOutGoingFlights] = useState([]);
  const [searchAirports, setSearchAirports] = useState([]);

  return (
    <FlightSearchContext.Provider
      value={{
        typeOfTrip,
        fromAirport,
        departureDate,
        returnDate,
        toAirport,
        outGoingFlights,
        searchAirports,
        setSearchAirports,
        // 记得把所有需要传递的setter也加上
      }}
    >
      {children}
    </FlightSearchContext.Provider>
  );
};

// 封装自定义hook,方便其他组件调用
export const useFlightSearch = () => useContext(FlightSearchContext);
  1. 修改原Flights组件,只保留自身UI
// Flights.tsx
const Flights = () => {
  // 如果需要用到上下文数据,用自定义hook获取即可
  // const { ... } = useFlightSearch();

  return <h1>Some UI</h1>;
};

export default Flights;
  1. 配置路由,让两个路由都在Provider范围内
// index.tsx路由配置
import { Routes, Route } from 'react-router-dom';
import { FlightSearchProvider } from './FlightSearchProvider';
import Flights from './Flights';
import FlightResults from './FlightResults';

function App() {
  return (
    <FlightSearchProvider>
      <Routes>
        <Route path="/flights" element={<Flights />} />
        <Route path="/flights/flight-results" element={<FlightResults />} />
      </Routes>
    </FlightSearchProvider>
  );
}

export default App;

这种方案把上下文管理和UI彻底解耦,后续新增需要上下文的页面也很方便,代码结构更清晰。

方案2:在Flights组件中根据路由判断是否显示自身UI

如果不想新增组件,可以通过路由路径判断,只在访问/flights时显示Flights的UI,访问子路由时仅渲染<Outlet/>。

修改Flights组件:

import { Outlet, useLocation } from 'react-router-dom';

const Flights = () => {
  const location = useLocation();
  // 只有当路径是/flights时才显示自身UI
  const shouldShowFlightsUI = location.pathname === '/flights';

  return (
    <FlightSearchContext.Provider
      value={{
        typeOfTrip,
        fromAirport,
        departureDate,
        returnDate,
        toAirport,
        outGoingFlights,
        searchAirports,
        setSearchAirports,
      }}
    >
      {shouldShowFlightsUI && <h1>Some UI</h1>}
      <Outlet />
    </FlightSearchContext.Provider>
  );
};

export default Flights;

路由配置保持嵌套:

<Routes>
  <Route path="/flights" element={<Flights />}>
    <Route path="flight-results" element={<FlightResults />} />
  </Route>
</Routes>

这种方案不需要额外拆分组件,但把路由逻辑耦合在了Flights组件里,适合快速临时解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 08:40:32