New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

react-router v4 使用 history 控制路由跳转 #3

Open
brickspert opened this Issue Sep 12, 2017 · 78 comments

Comments

Projects
None yet
@brickspert
Owner

brickspert commented Sep 12, 2017

react-router v4 使用 history 控制路由跳转

问题

当我们使用react-router v3的时候,我们想跳转路由,我们一般这样处理

  1. 我们从react-router导出browserHistory
  2. 我们使用browserHistory.push()等等方法操作路由跳转。

类似下面这样

import browserHistory from 'react-router';

export function addProduct(props) {
  return dispatch =>
    axios.post(`xxx`, props, config)
      .then(response => {
        browserHistory.push('/cart'); //这里
      });
}

but!! 问题来了,在react-router v4中,不提供browserHistory等的导出~~

那怎么办?我如何控制路由跳转呢???

解决方法

1. 使用 withRouter

withRouter高阶组件,提供了history让你使用~

import React from "react";
import {withRouter} from "react-router-dom";

class MyComponent extends React.Component {
  ...
  myFunction() {
    this.props.history.push("/some/Path");
  }
  ...
}
export default withRouter(MyComponent);

这是官方推荐做法哦。但是这种方法用起来有点难受,比如我们想在redux里面使用路由的时候,我们只能在组件把history传递过去。。

就像问题章节的代码那种场景使用,我们就必须从组件中传一个history参数过去。。。

2. 使用 Context

react-router v4Router 组件中通过Contex暴露了一个router对象~

在子组件中使用Context,我们可以获得router对象,如下面例子~

import React from "react";
import PropTypes from "prop-types";

class MyComponent extends React.Component {
  static contextTypes = {
    router: PropTypes.object
  }
  constructor(props, context) {
     super(props, context);
  }
  ...
  myFunction() {
    this.context.router.history.push("/some/Path");
  }
  ...
}

当然,这种方法慎用~尽量不用。因为react不推荐使用contex哦。在未来版本中有可能被抛弃哦。

3. hack

其实分析问题所在,就是v3中把我们传递给Router组件的history又暴露出来,让我们调用了~~

react-router v4 的组件BrowserRouter自己创建了history
并且不暴露出来,不让我们引用了。尴尬~

我们可以不使用推荐的BrowserRouter,依旧使用Router组件。我们自己创建history,其他地方调用自己创建的history。看代码~

  1. 我们自己创建一个history
// src/history.js

import createHistory from 'history/createBrowserHistory';

export default createHistory();
  1. 我们使用Router组件
// src/index.js

import { Router, Link, Route } from 'react-router-dom';
import history from './history';

ReactDOM.render(
  <Provider store={store}>
    <Router history={history}>
      ...
    </Router>
  </Provider>,
  document.getElementById('root'),
);
  1. 其他地方我们就可以这样用了
import history from './history';

export function addProduct(props) {
  return dispatch =>
    axios.post(`xxx`, props, config)
      .then(response => {
        history.push('/cart'); //这里
      });
}

4. 我非要用BrowserRouter

确实,react-router v4推荐使用BrowserRouter组件,而在第三个解决方案中,我们抛弃了这个组件,又回退使用了Router组件。

怎么办。 你去看看BrowserRouter源码,我觉得你就豁然开朗了。

源码非常简单,没什么东西。我们完全自己写一个BrowserRouter组件,然后替换第三种解决方法中的Router组件。嘿嘿。

讲到这里也结束了,我自己目前在使用第三种方法,虽然官方推荐第一种,我觉得用着比较麻烦唉。~

@wsgouwan

This comment has been minimized.

Show comment
Hide comment
@wsgouwan

wsgouwan Sep 21, 2017

貌似在组件中 可以直接使用 类似
let { history } = this.props; history.push('/cart')

wsgouwan commented Sep 21, 2017

貌似在组件中 可以直接使用 类似
let { history } = this.props; history.push('/cart')

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Sep 21, 2017

Owner

@wagouwan. 不可以的奥。除非你自己传了history过来。

Owner

brickspert commented Sep 21, 2017

@wagouwan. 不可以的奥。除非你自己传了history过来。

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Sep 22, 2017

Owner

@wsgouwan 你在<Route>组件的下一级使用是没问题的,但是你在孙子组件,或者redux里面是没法使用的哦。

Owner

brickspert commented Sep 22, 2017

@wsgouwan 你在<Route>组件的下一级使用是没问题的,但是你在孙子组件,或者redux里面是没法使用的哦。

@weishijun14

This comment has been minimized.

Show comment
Hide comment
@weishijun14

weishijun14 Oct 12, 2017

使用react-router-redux也可以的吧?不过这东西,支持react router4的还在开发中....

weishijun14 commented Oct 12, 2017

使用react-router-redux也可以的吧?不过这东西,支持react router4的还在开发中....

@weishijun14

This comment has been minimized.

Show comment
Hide comment
@weishijun14

weishijun14 Oct 12, 2017

store.dispatch(push('/foo'))

weishijun14 commented Oct 12, 2017

store.dispatch(push('/foo'))

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Oct 13, 2017

Owner

@weishijun14 可以的,不过一般开发项目中其实用不到react-router-redux的,除非有强烈的管理路由的需求~哈哈。

Owner

brickspert commented Oct 13, 2017

@weishijun14 可以的,不过一般开发项目中其实用不到react-router-redux的,除非有强烈的管理路由的需求~哈哈。

@regiondavid

This comment has been minimized.

Show comment
Hide comment
@regiondavid

regiondavid Nov 16, 2017

感觉这样子做的话,react展示组件逻辑不纯了,有没有更好的根据store去跳转的方案呢?

regiondavid commented Nov 16, 2017

感觉这样子做的话,react展示组件逻辑不纯了,有没有更好的根据store去跳转的方案呢?

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Nov 16, 2017

Owner

@regiondavid 不是很理解你的意思~~

Owner

brickspert commented Nov 16, 2017

@regiondavid 不是很理解你的意思~~

@hazeFlame

This comment has been minimized.

Show comment
Hide comment
@hazeFlame

hazeFlame Nov 17, 2017

好棒!!!!!!!!!!!!!!

hazeFlame commented Nov 17, 2017

好棒!!!!!!!!!!!!!!

@sysoft

This comment has been minimized.

Show comment
Hide comment
@sysoft

sysoft Nov 19, 2017

没有用mobx的嘛?

sysoft commented Nov 19, 2017

没有用mobx的嘛?

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Nov 20, 2017

Owner

@sysoft 没用过mobx,不过history的使用方式也是一样的。
第三种方法,用在任何地方都可以的哩。

Owner

brickspert commented Nov 20, 2017

@sysoft 没用过mobx,不过history的使用方式也是一样的。
第三种方法,用在任何地方都可以的哩。

@hazeFlame

This comment has been minimized.

Show comment
Hide comment
@hazeFlame

hazeFlame Nov 20, 2017

我用第一种了

hazeFlame commented Nov 20, 2017

我用第一种了

@dongkeying

This comment has been minimized.

Show comment
Hide comment
@dongkeying

dongkeying Dec 5, 2017

第一种方法里的"/some/Path"这个路由是在哪里配置的啊, 我也是使用的这种方法,但是 层级比较深,就不能跳转路由,地址栏改变,路由不跳转

dongkeying commented Dec 5, 2017

第一种方法里的"/some/Path"这个路由是在哪里配置的啊, 我也是使用的这种方法,但是 层级比较深,就不能跳转路由,地址栏改变,路由不跳转

@shengjudao

This comment has been minimized.

Show comment
Hide comment
@shengjudao

shengjudao Dec 6, 2017

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import RouterComponent from './router/router';
import {BrowserRouter} from 'react-router-dom';
import {Provider} from 'react-redux';
import stores from './store/store';
const storeA = stores();

ReactDOM.render(







, document.getElementById('root'));
registerServiceWorker();

我直接app组件里面,用this.props.history.push()还是能跳转,为什么啊,没有用withRouter

shengjudao commented Dec 6, 2017

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import RouterComponent from './router/router';
import {BrowserRouter} from 'react-router-dom';
import {Provider} from 'react-redux';
import stores from './store/store';
const storeA = stores();

ReactDOM.render(







, document.getElementById('root'));
registerServiceWorker();

我直接app组件里面,用this.props.history.push()还是能跳转,为什么啊,没有用withRouter

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Dec 6, 2017

Owner

@dongkeying /some/path就是普通的路由呀。。 你看看有没有报错信息。贴出来看看

Owner

brickspert commented Dec 6, 2017

@dongkeying /some/path就是普通的路由呀。。 你看看有没有报错信息。贴出来看看

@dongkeying

This comment has been minimized.

Show comment
Hide comment
@dongkeying

dongkeying Dec 6, 2017

页面没有报错,而且地址栏已经跳转到"/class/cart"的路由上了,但是页面没有跳转,重点就是我再刷新一下,就显示内容了... 然而直接跳转就不能,必须再刷新一下才显示
路由配置信息:
<Provider store={store}> <Router> <Switch> <Route exact path="/" component={Main} /> <Route path="/class/cart" component={Cart}></Route> <Route path="/search" component={Search} /> <Route component={NoMatch}></Route> </Switch> </Router> </Provider>
组件点击的时候:
gotoDetail(item){ // 传参方式是这样吗 ? this.props.history.push({ pathname: '/cart',state:{item}}); this.props.history.push("/class/cart"); } export default withRouter(Tab);
这个跟组件的嵌套深度有关系吗? 可能是我的路由嵌套太深了,是吗

dongkeying commented Dec 6, 2017

页面没有报错,而且地址栏已经跳转到"/class/cart"的路由上了,但是页面没有跳转,重点就是我再刷新一下,就显示内容了... 然而直接跳转就不能,必须再刷新一下才显示
路由配置信息:
<Provider store={store}> <Router> <Switch> <Route exact path="/" component={Main} /> <Route path="/class/cart" component={Cart}></Route> <Route path="/search" component={Search} /> <Route component={NoMatch}></Route> </Switch> </Router> </Provider>
组件点击的时候:
gotoDetail(item){ // 传参方式是这样吗 ? this.props.history.push({ pathname: '/cart',state:{item}}); this.props.history.push("/class/cart"); } export default withRouter(Tab);
这个跟组件的嵌套深度有关系吗? 可能是我的路由嵌套太深了,是吗

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Dec 6, 2017

Owner

@dongkeying 和嵌套深度没关系。写法也没啥问题呀。。再然后为什么不跳转,这个不太清楚。没报错信息有点奇怪哦。

Owner

brickspert commented Dec 6, 2017

@dongkeying 和嵌套深度没关系。写法也没啥问题呀。。再然后为什么不跳转,这个不太清楚。没报错信息有点奇怪哦。

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Dec 6, 2017

Owner

@shengjudao
这样的,路由组件
<Route exact path="/" component={Home}/>
在Home组件里面可以访问到history的。
但是子组件就访问不到了哦。除非你手动一级一级传下去。

Owner

brickspert commented Dec 6, 2017

@shengjudao
这样的,路由组件
<Route exact path="/" component={Home}/>
在Home组件里面可以访问到history的。
但是子组件就访问不到了哦。除非你手动一级一级传下去。

@dongkeying

This comment has been minimized.

Show comment
Hide comment
@dongkeying

dongkeying Dec 6, 2017

可是使用了withRouter 不就可以在层级较深的子组件访问到 history 了吗, 是不是就不需要一级一级传下去了

dongkeying commented Dec 6, 2017

可是使用了withRouter 不就可以在层级较深的子组件访问到 history 了吗, 是不是就不需要一级一级传下去了

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Dec 6, 2017

Owner

@dongkeying 是的。你的问题很可能代码写错了。既然路由变了,页面没变,肯定路由配置那边有问题。

Owner

brickspert commented Dec 6, 2017

@dongkeying 是的。你的问题很可能代码写错了。既然路由变了,页面没变,肯定路由配置那边有问题。

@yangxiufang1994

This comment has been minimized.

Show comment
Hide comment
@yangxiufang1994

yangxiufang1994 Dec 8, 2017

你好,我想问一下,你在第三种方式hack的时候,import createHistory from 'history/createBrowserHistory'; 不需要npm install --save history 吗?可以直接用?

yangxiufang1994 commented Dec 8, 2017

你好,我想问一下,你在第三种方式hack的时候,import createHistory from 'history/createBrowserHistory'; 不需要npm install --save history 吗?可以直接用?

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Dec 8, 2017

Owner

@yangxiufang1994 不用的,可以直接用。因为react-router v4 帮你安装了history啦。

Owner

brickspert commented Dec 8, 2017

@yangxiufang1994 不用的,可以直接用。因为react-router v4 帮你安装了history啦。

@yangxiufang1994

This comment has been minimized.

Show comment
Hide comment
@yangxiufang1994

yangxiufang1994 Dec 8, 2017

@brickspert 我只npm install react-router-dom ,我如果不安装,他就会提示我抱错,你也是安装的 react-router-dom 吗?

yangxiufang1994 commented Dec 8, 2017

@brickspert 我只npm install react-router-dom ,我如果不安装,他就会提示我抱错,你也是安装的 react-router-dom 吗?

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Dec 8, 2017

Owner

@yangxiufang1994 是只安装react-router-dom就可以的呀。

有错误可以贴出来。

Owner

brickspert commented Dec 8, 2017

@yangxiufang1994 是只安装react-router-dom就可以的呀。

有错误可以贴出来。

@yangxiufang1994

This comment has been minimized.

Show comment
Hide comment
@yangxiufang1994

yangxiufang1994 Dec 8, 2017

@brickspert import createHistory from 'history/createHashHistory'
const history = createHistory()
webpack3打包的时候就报Cannot find module 'history/createHashHistory', 我主要是想再ts 里跳一下路由
image

yangxiufang1994 commented Dec 8, 2017

@brickspert import createHistory from 'history/createHashHistory'
const history = createHistory()
webpack3打包的时候就报Cannot find module 'history/createHashHistory', 我主要是想再ts 里跳一下路由
image

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Dec 8, 2017

Owner

@yangxiufang1994 理论上装了react-router-dom就可以直接用了。 你看看你node_modules里面有木有history

Owner

brickspert commented Dec 8, 2017

@yangxiufang1994 理论上装了react-router-dom就可以直接用了。 你看看你node_modules里面有木有history

@yangxiufang1994

This comment has been minimized.

Show comment
Hide comment
@yangxiufang1994

yangxiufang1994 Dec 8, 2017

@brickspert 嗯嗯,我在重安装一下,试试看,谢谢你。

yangxiufang1994 commented Dec 8, 2017

@brickspert 嗯嗯,我在重安装一下,试试看,谢谢你。

@Lmagic16

This comment has been minimized.

Show comment
Hide comment
@Lmagic16

Lmagic16 Dec 10, 2017

我是采用您第三种方式,但是history.push之后页面路径会变化,但没有跳转。所以加了forceRefresh:true的初始化参数,强制每次路径变化刷新页面。这样页面就会有刷新,请问 可以有页面不刷新的路由跳转方式吗?

Lmagic16 commented Dec 10, 2017

我是采用您第三种方式,但是history.push之后页面路径会变化,但没有跳转。所以加了forceRefresh:true的初始化参数,强制每次路径变化刷新页面。这样页面就会有刷新,请问 可以有页面不刷新的路由跳转方式吗?

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Mar 29, 2018

Owner

@yushiwho 你是用的第二种方法还是第三种?

Owner

brickspert commented Mar 29, 2018

@yushiwho 你是用的第二种方法还是第三种?

@yushiwho

This comment has been minimized.

Show comment
Hide comment
@yushiwho

yushiwho commented Mar 29, 2018

@brickspert 第三种

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Mar 29, 2018

Owner

@yushiwho 第三种怎么会有 this.context??

Owner

brickspert commented Mar 29, 2018

@yushiwho 第三种怎么会有 this.context??

@yushiwho

This comment has been minimized.

Show comment
Hide comment
@yushiwho

yushiwho Mar 29, 2018

@brickspert 找到原因了,我的history用的是4.3.0,更新到最新的4.7.2就行了,4.3.0这个版本的history没有属性createHref,4.4.1加回去了,e20cebd

yushiwho commented Mar 29, 2018

@brickspert 找到原因了,我的history用的是4.3.0,更新到最新的4.7.2就行了,4.3.0这个版本的history没有属性createHref,4.4.1加回去了,e20cebd

@peterpanBest

This comment has been minimized.

Show comment
Hide comment
@peterpanBest

peterpanBest Apr 11, 2018

你好!我的项目可以正常跑起来,但是控制台一直提示:
warning.js:33 Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.
请问这是由于我的按需加载组件所引起的吗?还是别的原因?
谢谢!

peterpanBest commented Apr 11, 2018

你好!我的项目可以正常跑起来,但是控制台一直提示:
warning.js:33 Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.
请问这是由于我的按需加载组件所引起的吗?还是别的原因?
谢谢!

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Apr 11, 2018

Owner

@peterpanBest
把package-lock.json文件删掉,把node_modules删掉,
重新 npm install一下

Owner

brickspert commented Apr 11, 2018

@peterpanBest
把package-lock.json文件删掉,把node_modules删掉,
重新 npm install一下

@hello-astar

This comment has been minimized.

Show comment
Hide comment
@hello-astar

hello-astar Apr 28, 2018

你好,我有个问题
我在项目里用了BrowserRouter,/:id这种类型的路径可以直接访问到this.props.history,但是/:id/:date这样的没有props,加withroute也没用
咋办呢

hello-astar commented Apr 28, 2018

你好,我有个问题
我在项目里用了BrowserRouter,/:id这种类型的路径可以直接访问到this.props.history,但是/:id/:date这样的没有props,加withroute也没用
咋办呢

@hello-astar

This comment has been minimized.

Show comment
Hide comment
@hello-astar

hello-astar Apr 28, 2018

没事啦解决了谢谢

hello-astar commented Apr 28, 2018

没事啦解决了谢谢

@allenwei123

This comment has been minimized.

Show comment
Hide comment
@allenwei123

allenwei123 May 7, 2018

本人也是用了方法三,也出现了url改变了,UI没更新,请问怎么解决!

allenwei123 commented May 7, 2018

本人也是用了方法三,也出现了url改变了,UI没更新,请问怎么解决!

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert May 7, 2018

Owner

@allenwei123 你node_modules删了,重新npm install下试试。前面碰到的都是一些很低级的错误~你再仔细核对下代码

Owner

brickspert commented May 7, 2018

@allenwei123 你node_modules删了,重新npm install下试试。前面碰到的都是一些很低级的错误~你再仔细核对下代码

@allenwei123

This comment has been minimized.

Show comment
Hide comment
@allenwei123

allenwei123 May 7, 2018

allenwei123 commented May 7, 2018

@Buhaiyang

This comment has been minimized.

Show comment
Hide comment
@Buhaiyang

Buhaiyang Jun 10, 2018

你好 请问用createHistory怎么添加路由跳转提示,官方文档看完没用明白

Buhaiyang commented Jun 10, 2018

你好 请问用createHistory怎么添加路由跳转提示,官方文档看完没用明白

@wangchuan113057

This comment has been minimized.

Show comment
Hide comment
@wangchuan113057

wangchuan113057 Jun 13, 2018

你好。我使用的是第三种方法。但是必须添加forceRefresh: true才能成功,否则跳转失败。失败时状况如下:第一级路由通过Redirect跳转至第二级路由,二级路由回跳至一级路由失败;但是在二级路由所在页面刷新一次,则能跳转回一级路由;二级路由中操作即为 this.props.history.push('/') 。不知道为什么??

wangchuan113057 commented Jun 13, 2018

你好。我使用的是第三种方法。但是必须添加forceRefresh: true才能成功,否则跳转失败。失败时状况如下:第一级路由通过Redirect跳转至第二级路由,二级路由回跳至一级路由失败;但是在二级路由所在页面刷新一次,则能跳转回一级路由;二级路由中操作即为 this.props.history.push('/') 。不知道为什么??

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Jun 13, 2018

Owner

@wangchuan113057 我觉得是你姿势不对。第三种方法一共三步。你再核对下。尤其是第二步的:

<Router history={history}>  //这里的history对吗
Owner

brickspert commented Jun 13, 2018

@wangchuan113057 我觉得是你姿势不对。第三种方法一共三步。你再核对下。尤其是第二步的:

<Router history={history}>  //这里的history对吗
@wangchuan113057

This comment has been minimized.

Show comment
Hide comment
@wangchuan113057

wangchuan113057 Jun 13, 2018

按照你的步伐走的.... 就是这个写法。 在二级路由也是可以成功获取到history的,但是我发现从一级路由进入二级路由,在二级路由操作 this.props.history.push('/'),history 的action属性变成了replace,而不是push....我进行了监听发现了action 由push / 转变成了 replace /home

wangchuan113057 commented Jun 13, 2018

按照你的步伐走的.... 就是这个写法。 在二级路由也是可以成功获取到history的,但是我发现从一级路由进入二级路由,在二级路由操作 this.props.history.push('/'),history 的action属性变成了replace,而不是push....我进行了监听发现了action 由push / 转变成了 replace /home

@PhotonAlpha

This comment has been minimized.

Show comment
Hide comment
@PhotonAlpha

PhotonAlpha Jun 13, 2018

@brickspert 路由中有#的话 每次都会重新请求后台,怎么才能禁用# ?

PhotonAlpha commented Jun 13, 2018

@brickspert 路由中有#的话 每次都会重新请求后台,怎么才能禁用# ?

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Jun 14, 2018

Owner

@wangchuan113057 大兄弟,我第三种方法不是写的。文件里面跳转路由,这样用吗?

import history from './history';

history.push('xx');

你试试?

或者说,是不是路由里面配置拦截了。碰到/,自动定位到/home????

Owner

brickspert commented Jun 14, 2018

@wangchuan113057 大兄弟,我第三种方法不是写的。文件里面跳转路由,这样用吗?

import history from './history';

history.push('xx');

你试试?

或者说,是不是路由里面配置拦截了。碰到/,自动定位到/home????

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Jun 14, 2018

Owner

@PhotonAlpha 不是很懂你的意思呀~ 是说hashHistory吗?

按理单页面应用,不管有没有#,都不会向后台去请求呀。姿势不对?

Owner

brickspert commented Jun 14, 2018

@PhotonAlpha 不是很懂你的意思呀~ 是说hashHistory吗?

按理单页面应用,不管有没有#,都不会向后台去请求呀。姿势不对?

@PhotonAlpha

This comment has been minimized.

Show comment
Hide comment
@PhotonAlpha

PhotonAlpha Jun 14, 2018

@brickspert 非常感谢大佬能抽空回复我。
我重新描述一下,我使用的是 3. hack的配置,我在页面中打算使用锚点功能, <a href="#API" >Title</a> ,点击之后 页面URL变成http://localhost:4200/reveal#API,
这个时候,这个组件会重新加载

constructor(props) {
//这里会被调用
        super(props);
    }

这个情况是正常的吗?


大神我找到原因了:
我是参考你的 全家桶 文章的基础上使用了history,这个问题我刚才在全家桶文章的教程中验证过了。
bundle改造 src/router/Bundle.js
在 src/router/router.js 文件中

import UserInfo from 'bundle-loader?lazy&name=userInfo!pages/UserInfo/UserInfo';

const createComponent = (component) => (props) => (
    <Bundle load={component}>
        {
            (Component) => Component ? <Component {...props} /> : <Loading/>
        }
    </Bundle>
);

const getRouter = () => (
    <Router>
        <div>
            <ul>
                <li><Link to="/">首页</Link></li>
                <li><Link to="/userinfo">UserInfo</Link></li>
            </ul>
            <Switch>
                <Route exact path="/" component={createComponent(Home)}/>
                <Route path="/userinfo" component={createComponent(UserInfo)}/>
            </Switch>
        </div>
    </Router>
);

改造了component变成按需加载,这个时候 如果我URL中加入了变成了http://localhost:4200/reveal#API 之后, 组建会重新load(
constructor(props) { super(props); } componentDidMount() {} render() {}
) 都会被调用
当我把代码换回原始版本

import UserInfo from 'pages/UserInfo/UserInfo';
<Route path="/counter" component={UserInfo}/>

URL里面出现 #hash的时候 只会render了。

大神可以帮我把Bundle 组件里面bug修复一下吗?

PhotonAlpha commented Jun 14, 2018

@brickspert 非常感谢大佬能抽空回复我。
我重新描述一下,我使用的是 3. hack的配置,我在页面中打算使用锚点功能, <a href="#API" >Title</a> ,点击之后 页面URL变成http://localhost:4200/reveal#API,
这个时候,这个组件会重新加载

constructor(props) {
//这里会被调用
        super(props);
    }

这个情况是正常的吗?


大神我找到原因了:
我是参考你的 全家桶 文章的基础上使用了history,这个问题我刚才在全家桶文章的教程中验证过了。
bundle改造 src/router/Bundle.js
在 src/router/router.js 文件中

import UserInfo from 'bundle-loader?lazy&name=userInfo!pages/UserInfo/UserInfo';

const createComponent = (component) => (props) => (
    <Bundle load={component}>
        {
            (Component) => Component ? <Component {...props} /> : <Loading/>
        }
    </Bundle>
);

const getRouter = () => (
    <Router>
        <div>
            <ul>
                <li><Link to="/">首页</Link></li>
                <li><Link to="/userinfo">UserInfo</Link></li>
            </ul>
            <Switch>
                <Route exact path="/" component={createComponent(Home)}/>
                <Route path="/userinfo" component={createComponent(UserInfo)}/>
            </Switch>
        </div>
    </Router>
);

改造了component变成按需加载,这个时候 如果我URL中加入了变成了http://localhost:4200/reveal#API 之后, 组建会重新load(
constructor(props) { super(props); } componentDidMount() {} render() {}
) 都会被调用
当我把代码换回原始版本

import UserInfo from 'pages/UserInfo/UserInfo';
<Route path="/counter" component={UserInfo}/>

URL里面出现 #hash的时候 只会render了。

大神可以帮我把Bundle 组件里面bug修复一下吗?

@wangchuan113057

This comment has been minimized.

Show comment
Hide comment
@wangchuan113057

wangchuan113057 Jun 14, 2018

谢谢了..经过你的提醒我发现是路由拦截的问题....

wangchuan113057 commented Jun 14, 2018

谢谢了..经过你的提醒我发现是路由拦截的问题....

@GuoTeng

This comment has been minimized.

Show comment
Hide comment
@GuoTeng

GuoTeng Jun 20, 2018

对于方法三,如果用的是HashRouter,那么在history.js中应引入
import createHistory from 'history/createHashHistory';
同时,HashRouter标签中不再声明history属性
在需要使用的地方,直接引入history.js即可 import history from './history';
这样便不会出现url变化,但路由不跳转的情况,也就不需要forceRefresh: true

GuoTeng commented Jun 20, 2018

对于方法三,如果用的是HashRouter,那么在history.js中应引入
import createHistory from 'history/createHashHistory';
同时,HashRouter标签中不再声明history属性
在需要使用的地方,直接引入history.js即可 import history from './history';
这样便不会出现url变化,但路由不跳转的情况,也就不需要forceRefresh: true

@hugeorange

This comment has been minimized.

Show comment
Hide comment
@hugeorange

hugeorange Jun 20, 2018

按照您的 第三种方法成功了,但是有个疑问
现在在路由组件的儿子组件上:用 props依旧能看到 路由对象:history、location、match,不是说 我们用createBrowserHistoryreact-router-domBrowserRouter 代替了吗? 为什么还能看到这三个对象
image

hugeorange commented Jun 20, 2018

按照您的 第三种方法成功了,但是有个疑问
现在在路由组件的儿子组件上:用 props依旧能看到 路由对象:history、location、match,不是说 我们用createBrowserHistoryreact-router-domBrowserRouter 代替了吗? 为什么还能看到这三个对象
image

@brickspert

This comment has been minimized.

Show comment
Hide comment
@brickspert

brickspert Jun 20, 2018

Owner

@hugeorange 这个props里面的history对象,就是我们history.js里面定义的那个hisory对象。
并没有说替换路由,是自定义路由。
第二步,我们不是把自己定义的history传进去了么。

Owner

brickspert commented Jun 20, 2018

@hugeorange 这个props里面的history对象,就是我们history.js里面定义的那个hisory对象。
并没有说替换路由,是自定义路由。
第二步,我们不是把自己定义的history传进去了么。

@hxmilyy

This comment has been minimized.

Show comment
Hide comment
@hxmilyy

hxmilyy Jun 21, 2018

connected-react-router

hxmilyy commented Jun 21, 2018

connected-react-router

@linbaishuang

This comment has been minimized.

Show comment
Hide comment
@linbaishuang

linbaishuang Jul 4, 2018

请问有没有小demo可以给参考一下,因为对redux还不是很了解

linbaishuang commented Jul 4, 2018

请问有没有小demo可以给参考一下,因为对redux还不是很了解

@a12366456

This comment has been minimized.

Show comment
Hide comment
@a12366456

a12366456 Sep 17, 2018

使用第三种方法,完美解决

a12366456 commented Sep 17, 2018

使用第三种方法,完美解决

@noteScript

This comment has been minimized.

Show comment
Hide comment
@noteScript

noteScript Sep 18, 2018

@a12366456 将全局的方法绑定到react的配置文件中,使用脚手架创建的项目可以在你的index.js里面的顶部进行绑定。

// 在你使用React之前

...
import { createBrowserHistory /*createHashHistory */ } from 'history'
...

...
Object.assign(React.Component.prototype, {
  ...
  $router: createBrowserHistory()
})
...

// 使用React.Component

...
componentWillMount () { 
  console.log(this.$router)
}
...

noteScript commented Sep 18, 2018

@a12366456 将全局的方法绑定到react的配置文件中,使用脚手架创建的项目可以在你的index.js里面的顶部进行绑定。

// 在你使用React之前

...
import { createBrowserHistory /*createHashHistory */ } from 'history'
...

...
Object.assign(React.Component.prototype, {
  ...
  $router: createBrowserHistory()
})
...

// 使用React.Component

...
componentWillMount () { 
  console.log(this.$router)
}
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment