【问题标题】:How to use react-router-redux routeActions?如何使用 react-router-redux routeActions?
【发布时间】:2016-05-13 19:41:00
【问题描述】:

我正在尝试修改 react-router-redux 的示例代码。 https://github.com/rackt/react-router-redux/blob/master/examples/basic/components/Home.js

这是我的 Home.js

class Home extends Component {
    onSubmit(props) {
        this.props.routeActions.push('/foo');    
    }
}

我也有一个 mapDispatchToProps 。

function mapDispatchToProps(dispatch){
    return bindActionCreators({ routeActions },dispatch);
}

当我调用 onSubmit 函数时,我得到一个错误

Uncaught TypeError: this.props.routeActions.push is not a function

如果我在 onSubmit 中删除 this.props,则 URL 中的键已更改,但仍位于同一页面上。 从localhost:8080/#/?_k=iwio19localhost:8080/#/?_k=ldn1ew

有人知道怎么解决吗? 欣赏它。

【问题讨论】:

  • 请向我们展示您的完整 Home.js。

标签: reactjs react-router react-router-redux


【解决方案1】:

我不认为routeActions 被传递为props。你想做的是这样的:

import { routeActions } from 'react-router-redux'

this.props.dispatch(routeActions.push('/foo'));

【讨论】:

  • 这确实是你应该做的。当您 mapDispatchToProps 并且仍想使用调度时,就会出现问题。例如 connect(null, { someAction })(YourComponent) 将从道具中删除调度。知道如何在这种情况下使用 routeActions 吗?
  • 很抱歉我第一次没听懂。如果您将路由操作移动到您的操作文件并从那里调用路由函数会怎样。这样它就不会干扰 mapDispatchToProps 并且您可以在多个组件中重用该操作
【解决方案2】:

在评论中提供更明确的答案和我自己问题的答案。

是的,你可以这样做

import { routeActions } from 'react-router-redux'

this.props.dispatch(routeActions.push('/foo));

但是,正如我提到的 mapDispatchToProps 将覆盖它。 要解决此问题,您可以像这样绑定 routeAction:

import { bindActionCreators } from 'redux'
import { routeActions } from 'react-router-redux'

function mapDispatchToProps(dispatch) {
    return {
        routeActions: bindActionCreators(routeActions, dispatch),
    }
}

export default connect(null, mapDispatchToProps)(YourComponent)

现在你可以这样做了:this.props.routeActions.push('/foo')

仅供参考,这可以做得更整洁

function mapDispatchToProps(dispatch) {
    return {
        ...bindActions({routeActions, anotherAction}, dispatch)
    }
}

【讨论】:

  • 我认为 routeActions 不再是 react router redux 的一部分。你能确认一下吗?
  • 它说,Cannot read property 'push' of undefined(…),其中 import {push} 工作正常
【解决方案3】:

我可以通过这样做来让它工作

import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { routeActions } from 'react-router-redux'

export const Cmpt = React.createClass({ //code })

function mapDispatchToProps(dispatch) {
  return bindActionCreators({
    push: routeActions.push,
    //all your other action creators here
  }, dispatch)
}

export const CmptContainer = connect({}, mapDispatchToProps)(Cmpt)

然后你可以通过 props 使用 push this.props.push('some/cool/route')

【讨论】:

  • 这也解决了@Michiel 的问题
【解决方案4】:

更简洁

对于这些示例,我会像这样 curry mapDispatchToProps 函数:

bindActionDispatchers.js

import { bindActionCreators } from 'redux'

/** curries mapDispatchToProps with bindActionCreators to simplify React action dispatchers. */
export default function bindActionDispatchers(actionCreators) {
  if(typeof actionCreators === 'function')
    return (dispatch, ownProps) => bindActionCreators(actionCreators(ownProps), dispatch)
  return dispatch => bindActionCreators(actionCreators, dispatch)
}

Foo.js

import React from 'react'
import bindActionDispatchers from './bindActionDispatchers'
import { routeActions } from 'react-router-redux'
import * as appActions from './actions'

const Foo = ({ routeActions ...appActions }) => (
  <div>
    <button onClick={routeActions.push('/route')}>Route</button>
    <button onClick={appActions.hello('world')}>Hello</button>
  </div>
)

export default connect(null, bindActionDispatchers({ routeActions, ...appActions }))(Foo)

我将它打包成一个轻量级的 npm 包bind-action-dispatchers,并完成了单元测试和健全性检查。要使用此版本安装:

npm i -S bind-action-dispatchers

并使用以下命令导入函数:

import bindActionDispatchers from 'bind-action-dispatchers'

【讨论】:

    【解决方案5】:

    至于 react-router-redux v4:

    import { push } from 'react-router-redux';
    
    export class ExampleContainer extends React.Component {
      static propTypes = {
        changeRoute: React.PropTypes.func,
      };
    
      function mapDispatchToProps(dispatch) {
        return {
          changeRoute: (url) => dispatch(push(url)),
          dispatch,
        };
      }
    }
    
    export default connect(null, mapDispatchToProps)(ExampleContainer);
    

    然后:

    this.props.changeRoute('/foo');
    

    【讨论】:

    • 请@Mikhail 如果我在路由器组件中使用 browserHistory,如何以编程方式导航?我刚刚尝试了您的解决方案,但没有按预期工作。
    猜你喜欢
    • 1970-01-01
    • 2018-11-15
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 2019-11-04
    • 2018-07-16
    • 2018-10-16
    • 1970-01-01
    相关资源
    最近更新 更多