![](/img/trans.png)
[英]How to prevent browser back with react-router-dom and keep state
[英]How do I keep App() level state from resetting with react-router-dom in React.js?
我有一个钩子可以改变我的应用程序的背景颜色。 我希望在浏览站点时背景颜色保持不变,但路由器将此 state 重置为其原始使用状态“白色”。 我该如何正确实施?
使用 create-react-app 创建。
编辑以显示最小可重现示例:
import React, { useState } from 'react'; import { Route, Switch, BrowserRouter } from 'react-router-dom'; import './App.css'; export default function App() { const [color, setColor] = useState('white'); function changeBackground(value) { setColor(value); }; return ( <div className={color}> <BrowserRouter> <Navbar changeBackground={changeBackground} /> </BrowserRouter> </div> ); }; function Navbar(props) { return ( <div> <button onClick={() => props.changeBackground('red')}> Change Background Color </button> <div> <a href="/page1">Page 1</a> </div> <div> <a href="/page2">Page2</a> </div> <Switch> <Route exact path="/page1"><Page1 /></Route> <Route exact path="/page2"><Page2 /></Route> </Switch> </div> ); }; function Page1() { return ( <div> Page 1 </div> ); }; function Page2() { return ( <div> Page 2 </div> ); };
/* App.css */.white { background-color: white; }.red { background-color: red; }
添加最小可重现示例之前的先前代码:
import React, { useState } from 'react'; import { Route, Switch, BrowserRouter } from 'react-router-dom'; import './App.css'; import './assets/fonts/fonts.css'; import Navbar from './components/Navbar'; import Design from './components/Design'; import Develop from './components/Develop'; import Else from './components/Else'; import DesignTest from './pages/DesignTest'; function App() { const [backgroundColor, setBackgroundColor] = useState('white'); function changeBackground(value) { setBackgroundColor(value); }; return ( <div className={`w-screen min-h-screen ${backgroundColor}`}> {/* <Router> */} <Navbar changeBackground={changeBackground} /> <BrowserRouter> <Switch> <Route exact path="/"></Route> <Route exact path="/design"><Design /></Route> <Route exact path="/develop"><Develop /></Route> <Route exact path="/else"><Else /></Route> <Route exact path="/design/test"><DesignTest /></Route> </Switch> </BrowserRouter> </div> ); } export default App;
function Navbar(props) { return ( <div className="w-screen h-screen inline-grid grid-cols-12 grid-rows-6 tuffyBold tracking-widest"> <div className="row-start-1 row-end-3 col-start-1 col-end-7 text-right mt-auto mb-auto text-5xl"> TITLE </div> <div className="row-start-3 row-end-4 col-start-7 col-end-13 test-left mt-auto mb-auto text-4xl"> <a href="/design"> DESIGN </a> </div> <div className="row-start-4 row-end-5 col-start-7 col-end-13 test-left mt-auto mb-auto text-4xl"> <a href="/develop"> DEVELOP </a> </div> <div className="row-start-5 row-end-7 col-start-7 col-end-13 test-left mt-auto mb-auto text-4xl"> <a href="/else"> EVERY<br />THING<br />ELSE </a> </div> <div className="row-start-1 row-end-3 col-start-7 col-end-13 mt-auto mb-auto ml-auto mr-auto"> <div className="circle white" onClick={() => props.changeBackground('white')}></div> </div> <div className="row-start-3 row-end-4 col-start-1 col-end-7 mt-auto mb-auto ml-auto mr-auto"> <div className="circle yellow" onClick={() => props.changeBackground('yellow')}></div> </div> <div className="row-start-4 row-end-5 col-start-1 col-end-7 mt-auto mb-auto ml-auto mr-auto"> <div className="circle blue" onClick={() => props.changeBackground('blue')}></div> </div> <div className="row-start-5 row-end-6 col-start-1 col-end-7 mt-auto mb-auto ml-auto mr-auto"> <div className="circle dark" onClick={() => props.changeBackground('dark')}></div> </div> </div> ); } export default Navbar;
.yellow { background-color: #CDB900; color: black; }.blue { background-color: #009CCD; color: black; }.dark { background-color: #4B394E; color: white; }.white { background-color: white; color: black; }
我发现了我的问题。 我使用<a href="/#">
而不是从 react-router-dom 导入Link
,导致整个页面重新渲染。 这是按我的预期工作的版本:
import React, { useState } from 'react'; import { Route, Switch, BrowserRouter, Link } from 'react-router-dom'; import './App.css'; export default function App() { const [color, setColor] = useState('white'); function changeBackground(value) { setColor(value); }; return ( <div className={color}> <BrowserRouter> <Navbar changeBackground={changeBackground} /> </BrowserRouter> </div> ); }; function Navbar(props) { return ( <div> <button onClick={() => props.changeBackground('red')}> Change Background Color </button> <div> <Link to="/page1">Page 1</Link> </div> <div> <Link to="/page2">Page2</Link> </div> <Switch> <Route exact path="/page1"><Page1 /></Route> <Route exact path="/page2"><Page2 /></Route> </Switch> </div> ); }; function Page1() { return ( <div> Page 1 </div> ); }; function Page2() { return ( <div> Page 2 </div> ); };
/* App.css */.white { background-color: white; }.red { background-color: red; }
当我单击导航栏更改路线时,我遇到了同样的完整应用程序 state 刷新问题。 原来问题是由于没有使用 react 路由器提供的 Link 组件。
就我而言,我使用的是引导导航栏组件。 我从引导站点获得的代码创建了这样的导航栏链接:
<Nav.Link href="/home">Home</Nav.Link>
通过“href”的导航是这里的问题。 所以为了克服这个问题,我将 Nav.Link 包裹在 LinkContainer 中。 这使我可以从 Nav.Link 中删除 href,并使用 LinkContainer 中的“to”属性提供了路线 url。
<LinkContainer to="/home">
<Nav.Link>Home</Nav.Link>
</LinkContainer>
为了使用 LinkContainer,我必须安装并导入它。
npm install react-router-bootstrap
import { LinkContainer } from "react-router-bootstrap";
因为您的导航栏位于路由器组件之外,这意味着您单击的所有内容实际上都是在重新加载页面,而不是被Navbar
捕获。 在浏览器路由器中移动导航栏组件:
return (
<div className={`w-screen min-h-screen ${backgroundColor}`}>
{/* <Router> */}
<BrowserRouter>
<Navbar changeBackground={changeBackground} />
<Switch>
<Route exact path="/"></Route>
<Route exact path="/design"><Design /></Route>
<Route exact path="/develop"><Develop /></Route>
<Route exact path="/else"><Else /></Route>
<Route exact path="/design/test"><DesignTest /></Route>
</Switch>
</BrowserRouter>
</div>
);
似乎某些东西触发了重新渲染整个应用程序。 可能 React 开发者工具可以帮助你在代码中找到那个地方。
我创建了一个孤立的例子 - https://codesandbox.io/s/solitary-wood-8oi66?fontsize=14&hidenavigation=1&theme=dark&file=/src/App.js
在这个例子中,钩子中的颜色值也保存到浏览器 LocalStorage 中,并用作第一次渲染的默认值,因此可以在重新加载页面后保持背景颜色。 也许这就是您想要实现的目标。 但我不确定。
const defaultColor = localStorage.getItem("bgColor");
const [backgroundColor, setBackgroundColor] = useState(
defaultColor || "white"
);
function changeBackground(value) {
setBackgroundColor(value);
localStorage.setItem("bgColor", value);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.