Как использовать react-router-redux routeActions?

Я пытаюсь изменить пример кода react-router-redux. https://github.com/rackt/react-router-redux/blob/master/examples/basic/components/Home.js

Это мой дом.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, ключ в URL изменился, но его все еще на той же странице. От localhost:8080/#/?_k=iwio19 в localhost:8080/#/?_k=ldn1ew

кто-нибудь знает как это исправить? Ценить это.

5 ответов


не думаю routeActions передаются как props. Что вы хотите сделать это:

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

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

чтобы обеспечить немного более ясный ответ и ответ на мой собственный вопрос в комментариях.

Да, вы можете сделать

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

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

однако, как я уже упоминал, mapDispatchToProps переопределит это. Чтобы исправить это, вы можете связать routeActions следующим образом:

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')

просто FYI это можно сделать еще аккуратнее

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

Что касается 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');

я смог заставить его работать, сделав это

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)

затем вы можете использовать push via props this.props.push('some/cool/route')


Более Лаконично

для этих примеров я бы Карри функцию 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)
}

Фу.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-диспетчеры в комплекте с unit-тесты и проверки. Чтобы использовать эту версию установить с:

npm i -S bind-action-dispatchers

и импортировать функция с:

import bindActionDispatchers from 'bind-action-dispatchers'