使用 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
.
翻阅旧教程,似乎 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
.