I'm trying to modify the example code of react-router-redux. https://github.com/rackt/react-router-redux/blob/master/examples/basic/components/Home.js
this is my Home.js
class Home extends Component {
onSubmit(props) {
this.props.routeActions.push('/foo');
}
}
I also have a mapDispatchToProps for it.
function mapDispatchToProps(dispatch){
return bindActionCreators({ routeActions },dispatch);
}
When i called onSubmit function, I got an error
Uncaught TypeError: this.props.routeActions.push is not a function
If i remove this.props in onSubmit, the key in the URL changed but its still on the same page.
From localhost:8080/#/?_k=iwio19
to localhost:8080/#/?_k=ldn1ew
Anyone know how to fix it? Appreciate it.
I don't think routeActions
are passed as props
. What you want to do is this:
import { routeActions } from 'react-router-redux'
this.props.dispatch(routeActions.push('/foo'));
To provide a little more explicit answer and the answer to my own question in the comment.
Yes you can do
import { routeActions } from 'react-router-redux'
this.props.dispatch(routeActions.push('/foo));
However as I mentioned mapDispatchToProps will override this. To fix this you can bind the routeActions like so:
import { bindActionCreators } from 'redux'
import { routeActions } from 'react-router-redux'
function mapDispatchToProps(dispatch) {
return {
routeActions: bindActionCreators(routeActions, dispatch),
}
}
export default connect(null, mapDispatchToProps)(YourComponent)
Now you can do: this.props.routeActions.push('/foo')
Just FYI this can be done even neater
function mapDispatchToProps(dispatch) {
return {
...bindActions({routeActions, anotherAction}, dispatch)
}
}
As for 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);
then:
this.props.changeRoute('/foo');
I was able to get it working by doing this
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)
Then you can use push via props
this.props.push('some/cool/route')
More Concisely
For these examples, I'd curry the mapDispatchToProps function like so:
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)
I packaged this into a lightweight npm package bind-action-dispatchers complete with unit tests and sanity checks. To use this version install with:
npm i -S bind-action-dispatchers
and import the function with:
import bindActionDispatchers from 'bind-action-dispatchers'
来源:https://stackoverflow.com/questions/35196873/how-to-use-react-router-redux-routeactions