yab*_*ugh 5 javascript reactjs react-router react-router-dom react-context
浏览旧教程,React Router v5 似乎支持使用上下文 API 在不同路由之间共享状态,但我找不到 Router v6 的类似用法。
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>
);
Run Code Online (Sandbox Code Playgroud)
然后你可以使用useContext钩子访问状态
const {value, setValue} = useContext(UserContext);
Run Code Online (Sandbox Code Playgroud)
当尝试将此实现与 v6 一起使用(将降级的 v5 组件替换为新的 v6 组件)时,您将遇到错误,因为您只能将<Route>组件作为路由器中的子组件。
是否可以跨 React Router V6 路由与全局上下文存储共享状态?
以下是我在 V6 实现上的尝试:
索引.js
import { BrowserRouter as Router } from "react-router-dom";
ReactDOM.render(
<Router>
<App />
</Router>,
document.getElementById("root")
);
Run Code Online (Sandbox Code Playgroud)
应用程序.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>
</>
);
Run Code Online (Sandbox Code Playgroud)
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>
);
}
Run Code Online (Sandbox Code Playgroud)
此解决方案的问题是,当其中一条路由发生更改时,状态仍未全局更新。
例如,/dashboard如果我使用setValuethen 更改值,它将反映更改/dashboard,但如果我导航到/configuration或刷新value将恢复到原始value状态,在这种情况下为“初始状态”。App.js(如果我创建一个将使用的函数setValue并将该函数传递给 Provider,这也是效果)
我确信我可以使用 React Redux 来解决这个问题,但它实际上只是我需要在路由之间共享的一两个数据 - 实现所有所需的 redux 样板等似乎有点矫枉过正,而且似乎是一个常见的用例该背景应该支持。
它很简单,您需要Router在您的DataProvider.
// import { BrowserRouter as Router } from "react-router-dom";
ReactDOM.render(
<App />,
document.getElementById("root")
);
Run Code Online (Sandbox Code Playgroud)
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>
);
}
Run Code Online (Sandbox Code Playgroud)
还要确保您使用Link路由器导航到不同的页面。使用任何其他刷新页面的“a”标签等都会重置context.