后退按钮在 React 中显示空白页
Posted
技术标签:
【中文标题】后退按钮在 React 中显示空白页【英文标题】:Back button displays blank page in React 【发布时间】:2020-11-06 14:05:30 【问题描述】:我正在尝试使用浏览器中的后退按钮,以便用户可以在我的 react 应用程序中顺利返回。它有时适用于特定组件。例如,当我从 Supervisores 到 Anfitrion 时它可以工作,但是当我从 Anfitrion 到 Suprvisores 或任何动态路线时它都不起作用。 这是我的路由器中的内容。
<Router>
<Switch>
<Route exact path="/Anfitrion" component=PropiedadesRegistradas/>
<Route path='/AgregarPropiedad' component=AgregarPropiedad />
<Route path= "/AreasRegistradas/:propertyId" component=AreasRegistradas/>
<Route path= "/ItemsAreasRegistradas/:propertyId" component=ItemsAreasRegistradas/>
<Route path="/ElementosDeArea/:areaId" component = ElementosDeArea />
<Route path="/AgregarItems/:areaId/:propertyId" component = AgregarItems />
<Route path="/AgregarArea/:propertyId" component = AgregarArea />
<Route path="/supervisores" component=Supervisores/>
<Route path="/historial" component=Historial/>
<Route path="/desinfeccion" component=Desinfeccion/>
<Route path="/folios" component=Folios/>
<Route path="/areasRegistradas" component=AreasRegistradas/>
<Route path= "/agregarSupervisor" component=AgregarSupervisor/>
<Route path="/detalle/:servicio/:hostId" component=Detalle />
<Route render=()=> <h3>Not found</h3>/>
</Switch>
</Router>
这是我尝试使用 useHistory Hook 的方法,但是当我点击按钮时它会显示一个黑页:
import React from 'react'
import Button from '@material-ui/core/Button';
import useHistory from 'react-router-dom'
export default function AgregarItems(match, props)
let history = useHistory()
return(
<div>
<Button onClick=() => history.goBack()>Atrás</Button>
</div>
)
当我使用浏览器的后退和前进按钮时,它也会显示一个空白页面。我正在阅读有关 React 路由器的历史记录,但我还没有发现任何有用的东西,当我这样做时,它是针对 React Router v3 的。
感谢您的帮助!
我正在使用:
"react-dom": "^16.13.1", “反应路由器”:“^5.2.0”, "react-router-dom": "^5.2.0",【问题讨论】:
我需要再次仔细检查这一点,但您是否尝试将组件包装在withRouter
中,例如:import withRouter from 'react-router-dom'; const AgregarItems = () => history.goBack() .... export default withRouter(AgregarItems);
【参考方案1】:
我通过从我的 rails 应用程序中删除 turbolinks 解决了这个问题。信用:page is not rendering when I click back button with react-router
【讨论】:
就是这样。它解决了我在 Rails API/React 前端项目中的问题【参考方案2】:刚刚使用 CRA 进行了测试。看看并试试这个。
您可能不需要使用withRouter
文件: ./PageOne.js
import React from 'react';
import Link from 'react-router-dom'
const PageOne = props => <div><h1>Click below</h1><Link to="/page2">Page 2</Link></div>;
export default PageOne;
文件: ./PageTwo.js
import React from 'react';
const PageTwo = props => <div><h1>Click Below</h1><button onClick=() => props.history.goBack()>Go Back</button></div>;
export default PageTwo;
文件: ./index.js
import React from 'react';
import ReactDOM from 'react-dom';
import BrowserRouter, Route, Switch from 'react-router-dom'
import PageOne from './PageOne';
import PageTwo from './PageTwo';
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<Switch>
<Route exact path="/" component=PageOne />
<Route exact path="/page2" component=PageTwo />
</Switch>
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
========== 更新 ===========
对于作为抽象<PrivateRoute>
的角色的路由中间件
点击下面的运行代码sn-p,看看它是如何获得权限的。
// IMPORTS
const useState = React;
// *** only allows HashRouter
// But replace with BrowserRouter
const HashRouter, Switch, Route, Link, Redirect = ReactRouterDOM;
/**
*
*/
const NotPermitted = props => <div><h1>Not Permitted</h1><p>You need to be</p> <code>admin@admin.com</code><p> </p><Link to="/">Go Back Home</Link></div>;
/**
*
*/
const AdminOnly = props => <div><h1>Admin Only</h1><p>You should only see this is your email is "admin@admin.com"</p></div>;
/**
*
*/
const Dashboard = props => <div><h1>Dashboard</h1><p>Links</p><ul><li><Link to="/private">Private Page</Link></li><li><Link to="/adminonly">Admin Only</Link></li></ul></div>;
/**
*
*/
const Login = props =>
const onSubmit = event =>
event.preventDefault();
if (props.login)
props.login(
email: event.target.email.value,
password: event.target.password.value
);
return <div>
<h1>Login</h1>
<form onSubmit=onSubmit>
<p><input type="text" name="email" placeholder="Email" /></p>
<p><input type="password" name="password" placeholder="Password" /></p>
<p><button type="submit">Submit</button></p>
</form>
</div>
/**
*
*/
const PrivatePage = props => <div><h1>Private Page</h1><p>Anyone logged in can see this page.</p><Link to="/">Go Back Home</Link></div>;
/**
*
*/
const PrivateRoute = props =>
const component: Component, permitted, user, ...rest = props;
return (
<Route
...rest
render=(routeProps) =>
user
? permitted
? <Component ...routeProps />
: <Redirect to="/notpermitted" />
: <Redirect to="/login" />
/>
);
/**
*
*/
const App = props =>
const [user, setUser] = useState(null);
const login = ( email, password ) =>
setUser(
email,
);
const logout = () =>
setUser(null);
return <div>
user && <button onClick=logout>Logout</button>
<Switch>
<Route exact path="/" render=() => user ? <Redirect to="/dashboard" /> : <Redirect to="/login" /> />
<Route exact path="/login" render=(routeProps) => !user ? <Login login=login ...routeProps /> : <Redirect to="/dashboard" /> />
<PrivateRoute user=user permitted=true exact path="/dashboard" component=Dashboard />
<PrivateRoute user=user permitted=user && user.email === 'admin@admin.com' exact path="/adminonly" component=AdminOnly />
<PrivateRoute user=user permitted=true exact path="/private" component=PrivatePage />
<PrivateRoute user=user permitted=true exact path="/notpermitted" component=NotPermitted />
</Switch>
<hr />
user && <p><small>Debug JSON</small></p>
user && <pre><code>JSON.stringify(user, null, ' ')</code></pre>
<p><small>Redirect Tests</small></p>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/login">Login</Link></li>
<li><Link to="/dashboard">Dashboard</Link></li>
<li><Link to="/adminonly">Admin Only</Link></li>
<li><Link to="/private">Private</Link></li>
<li><Link to="/notpermitted">Not Permitted</Link></li>
</ul>
</div>
/**
*
*/
const Index = props =>
return <div>
<HashRouter>
<App />
</HashRouter>
</div>
ReactDOM.render(<Index />, document.querySelector('#root'));
body
font-family: Arial, sans-serif;
padding: 20px;
margin: 0;
form
display: block;
input
height: 40px;
padding: 0 12px;
border-radius: 4px;
border: 1px solid #efefef;
min-width: 200px;
button
display: block;
height: 40px;
padding: 0 20px;
background: blue;
color: white;
border-radius: 4px;
border: none;
pre
display: block;
margin-top: 20px;
code
display: block;
background: #efefef;
padding: 20px;
h1
font-size: 21px;
padding-bottom: 20px;
border-bottom: 1px solid #efefef;
margin-bottom: 20px;
hr
border: none;
height: 1px;
background: #efefef;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/react-router/umd/react-router.min.js"></script>
<script src="https://unpkg.com/react-router-dom/umd/react-router-dom.min.js"></script>
<div id="root"></div>
【讨论】:
我试过这个,实际上我使用 history.goBack() 从一个组件转到主组件“/Anfitrion”并且它有效!但由于某种原因它如果我想去别的地方就不行了。 你所说的“去别的地方”是什么意思,比如去不同的路线?示例history.push("/page3")
?
没错!我的意思是,我可以毫无问题地执行 history.push(),但是当我单击浏览器上的后退按钮时,它会显示一个空白页面
这是本地开发(标准 CRA)还是生产构建(纱线构建...等)?
我认为这与之前的身份验证过程有关。因为我直接重定向到“/Anfitrion”。关于身份验证后如何使用反应路由器的任何想法?【参考方案3】:
我知道这个问题很老,但我会发布我的答案,因为我遇到了这个问题,我希望找到更简单的解决方案。
用例:React 作为前端,Ruby on Rails 6 作为后端。
如果您在浏览器中按“返回”并且您的 React 应用呈现空白页面,您有两种解决方案:
-
Remove TurboLinks gem
调整您的应用,使其与 TurboLinks 一起使用。
如果你想删除 TurboLinks:
-
从 Gemfile 中移除 gem 'turbolinks', '~> 5'
从 app/assets/javascript/application.js 中删除 //= 需要 turbolinks
从 app/views/layouts/application.html.erb 中删除 'data-turbolinks-track': 'reload' (x2)
运行 yarn remove turbolinks
运行 rails tmp:cache:clear
第 4 步是与 Rails 5 的主要区别。 致 this 帖子。
如果你想保留 TurboLinks
你的 React 应用的 index.js 看起来像这样:
document.addEventListener('DOMContentLoaded', () =>
ReactDOM.render(
<App />,
document.body.appendChild(document.createElement('div')),
)
)
你必须让它看起来像这样:
document.addEventListener('turbolinks:load', () =>
ReactDOM.render(
<App />,
document.body.appendChild(document.createElement('div')),
)
)
基本上,您将事件侦听器从 DOMContentLoaded
更改为 turbolinks:load
。
如果您停在这里,您会注意到现在当您在应用程序中来回前进时,组件会在同一页面上多次呈现。
要解决此问题,请进入application.html.erb
并在<head>
标签中添加此代码的sn-p
<meta name='turbolinks-cache-control' content='no-cache'>
恭喜!现在,您的 React on Rails 应用程序可以与 TurboLinks 一起使用。
【讨论】:
以上是关于后退按钮在 React 中显示空白页的主要内容,如果未能解决你的问题,请参考以下文章
为什么Android应用程序在退出带有后退按钮的应用程序时显示空白屏幕React Native Navigation?