使用 Context API 在 React router v6 路由之间共享状态

Sharing state across React router v6 routes using Context API

翻阅旧教程,似乎 React Router v5 支持使用上下文在不同路由之间共享状态 API 但我找不到 Router v6 的类似用法。

React Router v5 实现我正在尝试做的事情:

const [user, setUser] = useState(null);
 return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/about/">About</Link>
            </li>
          </ul>
        </nav>
        <UserContext.Provider value={user,setUser}>
          <Route path="/" exact component={Index} />
          <Route path="/about/" component={About} />
        </UserContext.Provider>
      </div>
    </Router>
  );

然后您可以使用 useContext 钩子

访问状态
const {value, setValue} = useContext(UserContext);

v6 实现

当尝试将此实现与 v6 一起使用时(将降级的 v5 组件替换为新的 v6 组件)您将 运行 出错,因为您只能将 <Route> 组件作为路由器中的子组件.

是否可以跨 React Router V6 路由与全局上下文存储共享状态?

以下是我在 V6 实现中的尝试:

index.js

import { BrowserRouter as Router } from "react-router-dom";

ReactDOM.render(
  <Router>
    <App />
  </Router>,
  document.getElementById("root")
);

App.js

const [value, setValue] = useState("initial state");

  return (
    <>
      <Header props={(key, setKey)} />
      <DataContext.Provider value={(value, setValue)}>
        <Route path="/" element={<Dashboard />} />
        <Route path="/dashboard" element={<Dashboard />} />
        <Route path="/configuration" element={<Configuration />} />
      </DataContext.Provider>
    </>
  );

App.js 不同的方法

  const [value, setValue] = useState("initial state");

  return (
    <DataContext.Provider value={(value, setValue)}>
      <Header props={(key, setKey)} />
      <Routes>
        <Route path="/" element={<Dashboard />} />
        <Route path="/dashboard" element={<Dashboard />} />
        <Route path="/configuration" element={<Configuration />} />
      </Routes>
    </DataContext.Provider>
  );
}

此解决方案的问题是,当其中一条路线发生变化时,状态仍未全局更新。 例如 /dashboard 中的 如果我使用 setValue 更改值,那么它将反映 /dashboard 中的更改,但如果我导航到 /configuration或刷新 value 将恢复为原始 value,在这种情况下为“初始状态”。 (这也是如果我在 App.js 中创建一个将使用 setValue 的函数并将函数传递给 Provider 的效果)

我确定我可以使用 React Redux 来解决这个问题,但它实际上只是我需要在路由之间共享的一两个数据 - 似乎实现所有必需的 redux 样板等似乎有点过头了而且似乎就像上下文应该支持的常见用例。

很简单,您需要在 DataProvider 中使用 Router

index.js

// import { BrowserRouter as Router } from "react-router-dom";

ReactDOM.render(
  <App />,
  document.getElementById("root")
);

app.js

import { BrowserRouter as Router } from "react-router-dom";
// .....
// .....
// .....
 const [value, setValue] = useState("initial state");

  return (
    <DataContext.Provider value={(value, setValue)}>
      <Header props={(key, setKey)} />
      <Router>
      <Routes>
        <Route path="/" element={<Dashboard />} />
        <Route path="/dashboard" element={<Dashboard />} />
        <Route path="/configuration" element={<Configuration />} />
      </Routes>
      </Router>
    </DataContext.Provider>
  );
}

还要确保您正在使用路由器的 Link 导航到不同的页面。使用任何其他刷新页面的 'a' 标签等将重置 context.