reactjs - 如何在 React Router 和 outlet 中不使用高阶函数的情况下在两个组件之间共享数据

标签 reactjs typescript react-router react-router-dom

我有两个组件,一个叫做 <Flights/>另一个叫<FlightResults/> .

Flights 为应用程序的其余部分呈现上下文提供程序。

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

export default Flights;
const FlightResults = () => {
  const { toAirport, outGoingFlights } = useContext(FlightSearchContext);

  return (
    <div>Flight results</div>
  )
}

export default FlightResults

现在我在我的 index.tsx 中声明两条路线像这样归档。

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { Routes, Route } from "react-router";
import { BrowserRouter } from "react-router-dom";

import Flights from "./Components/Flights/Flights";
import FlightResults from "./Components/Flights/FlightResults";

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);

root.render(
  <React.StrictMode>
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<App />}>
          <Route path="/flights" element={<Flights />} index />
          <Route path="/flights/flight-results" element={<FlightResults />} />
        </Route>
      </Routes>
    </BrowserRouter>
  </React.StrictMode>
);

FlightResultsFlights 的子路由它需要访问在 Flights 中声明的上下文数据组件。

目前一切正常,但 FlightResults无法访问 Flights 中的数据组件。

经过大量搜索后,我发现我应该将我的子组件包装在 index.tsx 中文件如下。

        <Route path="/" element={<App />}>
          <Route path="/flights" element={<Flights />} index>
            <Route path="/flight-results" element={<FlightResults />} />
          </Route>
          <Route path="/hotels" element={<Hotel />} />
          <Route path="/taxi" element={<Taxi />} />
        </Route>

虽然这有效 FlightResults UI 未显示在 /flights/flightresults 下, 一个可能的解决方法是渲染 Outlet Flights 上的组件像下面的组件

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

export default Flights;

以上确实有效,但现在两个 UI 都显示在 /flights/flightresults/ 上.as in FlightsFlightResults显示在相同的 URL 上。

如何让正确的组件呈现在正确的 URL 上,同时还能访问上下文数据?

最佳答案

问题

问题是您正在将您希望独占“/flights” 上呈现的内容与您希望提供给多条路线的数据混合在一起。

解决方案

当前 Flights 组件的 FlightSearchContext.Provider 组件应该重构为 Layout RouteFlights 中的 UI 部分保留在其自己的路线上。

例子:

const FlightsProvider = () => (
  <FlightSearchContext.Provider
    value={{
      typeOfTrip,
      fromAirport,
      departureDate,
      returnDate,
      toAirport,
      outGoingFlights,
      searchAirports,
      setSearchAirports,
    }}
  >
    <Outlet/>     
  </FlightSearchContext.Provider>
);
<Route path="/flights" element={<FlightsProvider />}>
  <Route
    index                 // <-- "/flights"
    element={<Flights />}
  />
  <Route
    path="flight-results" // <-- "/flights/flight-results"
    element={<FlightResults />}
  />
</Route>

如果您真的不想使用Outlet组件,那么您可以简单地解除FlightSearchContext.Provider 在 ReactTree 中更高。在这种情况下,FlightsProvider 成为普通的 Wrapper 组件。

例子:

const FlightsProvider = ({ children }) => (
  <FlightSearchContext.Provider
    value={{
      typeOfTrip,
      fromAirport,
      departureDate,
      returnDate,
      toAirport,
      outGoingFlights,
      searchAirports,
      setSearchAirports,
    }}
  >
    {children}     
  </FlightSearchContext.Provider>
);
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <FlightsProvider>
        <Routes>
          <Route path="/" element={<App />}>
            <Route path="/flights" >
              <Route index element={<Flights />} />
              <Route path="flight-results" element={<FlightResults />} />
            </Route>
          </Route>
        </Routes>
      </FlightsProvider>
    </BrowserRouter>
  </React.StrictMode>
);

关于reactjs - 如何在 React Router 和 outlet 中不使用高阶函数的情况下在两个组件之间共享数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74824481/

相关文章:

javascript - Firebase - 在 localStorage 对象有效时保持用户登录

typescript :从通用接口(interface)中省略属性

javascript - rxjs 中 do 和 subscribe 的区别

nginx - React-router 和 nginx

javascript - React 将 prop 传递给组件返回 undefined

reactjs - react 路由器 v4。需要防止组件重新渲染(尝试构建类似 instagram 的图像网格)

reactjs - 如何修复 React-Redux 应用程序中的 431 请求 header 字段过大

javascript - 如何将数据从元素传递到 ReactJS 中的操作?

reactjs - react native 0.52 : Metro Bundler has encountered an internal error

reactjs - 如何使用 react-router 执行多个可选参数?