当我使用 react-router 单击后退按钮时页面未呈现 [英] page is not rendering when I click back button with react-router

查看:79
本文介绍了当我使用 react-router 单击后退按钮时页面未呈现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含此顶级组件的应用程序:

从'react'导入React;从 'react-dom' 导入 ReactDOM;import { BrowserRouter as Router } from 'react-router-dom';从'react-redux'导入{提供者};从'../lib/Store.js'导入{createStore};从'../components/application'导入应用程序;document.addEventListener('DOMContentLoaded', () => {ReactDOM.render(<提供者商店={createStore()}><路由器><应用程序/></路由器></提供者>,document.body.appendChild(document.createElement('div')));});

当我单击 时,页面会正确呈现,但如果我使用浏览器返回(MacOS 上为 Chrome 60.0.3112.113),则页面为空白.

有一个非常奇怪但可重复的场景:

  • 导航到任何页面 -> 页面呈现正确
  • 点击 -> 页面正确呈现
  • 点击返回按钮 -> 空白页
  • 点击前进按钮 -> 空白页
  • 单击后退按钮 -> 呈现第 1 步中的页面!!
  • 点击前进 -> 没有渲染变化,第 1 步中的页面保持渲染
  • 点击返回 -> 空白页面再次呈现
  • 点击前进 -> 仍然是空白页
  • 单击返回 -> 步骤 1 中的页面再次呈现...

似乎每隔一次我点击它时,后退按钮就会起作用.问题是,当我让原始页面呈现每一次其他回点击时,原始 不再有效.它带我到正确的网址,但页面是空白的.

我确定这与生命周期回调或类似问题有关,但我不知道如何在正确的位置强制更新以解决这种情况.

为了清楚起见,这是 Application 组件的组成:

从'react'导入React;从'react-router-dom'导入{路由,开关};从 'prop-types' 导入 PropTypes;从 './TopNav' 导入 TopNav;从'./BoardsDashboard'导入BoardsDashboard;从 './BoardContainer' 导入 BoardContainer;从 './CardContainer' 导入 CardContainer;从'../actions/BoardActions'导入{fetchBoards};类应用程序扩展了 React.Component {静态上下文类型 = {商店:PropTypes.object}使成为() {返回 (<div><TopNav/><Route path='/cards/:cardId' 精确组件={BoardContainer}/><Route path='/cards/:cardId' 精确组件={CardContainer}/><Route path='/boards/:boardId' 精确组件={BoardContainer}/><Route path='/' 精确组件={BoardsDashboard}/>

);}}导出默认应用程序;

使用 redux-devtools,每次单击后退和前进按钮时,我都可以看到正在调度的所有正确操作.我认为我的组件没有更新,因为当这些操作完成时 store 没有变化,但我需要它们在没有变化的情况下呈现.

当我需要手动访问商店时,我确实有一些 React.Component 类作为容器组件.每当我不需要手动访问商店时,我都会使用 react-redux 中的 connect.TopNav 是一个展示组件,所以至少它应该呈现,因为它不依赖于商店(至少我认为它应该).

解决方案

这最终是 Turbolinks 对后退按钮以及 React Router 做出反应.我从 Rails 应用中删除了 Turbolinks,问题解决了.

I have an application that has this top level component:

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import { Provider } from 'react-redux';
import { createStore } from '../lib/Store.js';

import Application from '../components/application';

document.addEventListener('DOMContentLoaded', () => {
  ReactDOM.render(
    <Provider store={createStore()}>
      <Router>
        <Application />
      </Router>
    </Provider>,
    document.body.appendChild(document.createElement('div'))
  );
});

When I click on a <Link>, the page renders properly, but if I go back with the browser (Chrome 60.0.3112.113 on MacOS), the page is blank.

There is a very weird but repeatable scenario:

  • Navigate to any page -> page renders properly
  • Click <Link> -> page renders properly
  • Click back button -> blank page
  • Click forward button -> blank page
  • Click back button -> page from step 1 renders!!
  • Click forward -> No render change, the page from step 1 stays rendered
  • Click back -> blank page renders again
  • Click forward -> still a blank page
  • Click back -> page from step 1 renders again...

It seems that every other time I click it, the back button works. The thing is, the original <Link> no longer works when I get the original page to render every other back click. It takes me to the right url, but the page is blank.

I'm sure this has to do with lifecycle callbacks or something of the like, but I can't figure out how to force an update in the correct place to fix the situation.

For clarity, this is what the Application component consists of:

import React from 'react';
import { Route, Switch } from 'react-router-dom';
import PropTypes from 'prop-types';

import TopNav from './TopNav';
import BoardsDashboard from './BoardsDashboard';
import BoardContainer from './BoardContainer';
import CardContainer from './CardContainer';

import { fetchBoards } from '../actions/BoardActions';

class Application extends React.Component {
  static contextTypes = {
    store: PropTypes.object
  }

  render() {
    return (
      <div>
        <TopNav />

        <Route path='/cards/:cardId' exact component={BoardContainer} />
        <Route path='/cards/:cardId' exact component={CardContainer} />
        <Route path='/boards/:boardId' exact component={BoardContainer} />

        <Route path='/' exact component={BoardsDashboard} />
      </div>
    );
  }
}

export default Application;

Using redux-devtools I can see all of the correct actions being dispatched each time I click the back and forward button. I think that my components are not updating because there is no change to the store when these actions complete, but I need them to render even with no change.

I do have some React.Component classes as container components when I need to access the store manually. Whenever I don't need to access the store manually, I use connect from react-redux. TopNav is a presentational component though, so at the very least it should render since it doesn't rely on the store (at least I think it should).

解决方案

This ended up being Turbolinks reacting to the back button as well as React Router. I removed Turbolinks from my Rails app and the problem is resolved.

这篇关于当我使用 react-router 单击后退按钮时页面未呈现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆