4

In my component class I have this.props which contains history object which contains transitionTo function.

render() {
    console.log(this.props)

    return (
      <div>
        <button onClick={actions.myAction}>My button</button>
      </div>

Here my button is calling myAction which when completes wants to route to some other location. I want to access this transitionTo function in my action and performs something like router.transitionTo("/page1")

For this I should get history object which contains transitionTo function. So how can I pass this.props.history object to actions. When I do onClick={actions.myAction(this.props.history)} my button is not being rendered..

Any help

gamer
  • 5,673
  • 13
  • 58
  • 91

2 Answers2

1

I do not agree with your approach, but find bellow the solution to your problem:

handleBtnClick() {
  actions.MyAction(this.props.history);
}

render() {
  return (
    <div>
       <button onClick={ this.handleBtnClick.bind(this) }>My button</button>
    </div>
  );
}

When your button is clicked the function handleBtnClick() is invoked and there you can call your action and pass any props you want.

onClick expects a function expression (something that evaluates to a function expression). You are not supposed to make complex calls in there such as actions.myAction(this.props.history).

I would suggest you to consider using react-router-redux and handle url transitions using routeActions and custom redux middleware. I can expand this approach if you are interested.

EDIT:

If you use react-router-redux then you should take advantage of methods in routeActions. The method you need in this case is push(). So, if you want to transition to the /user/account url you just call dispatch(routeActions.push('/user/account')) and react-router-redux will handle the transition.

Eg:

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

// Action creator    
function mySuperAction(flag) {
  return (dispatch, getState) => {
    dispatch(routeActions->push('/user/account'));
  }
});

You need to have your store properly setup with react-router-redux in order for this to work.

Or from a component:

import { routeActions } from 'react-router-redux';
import { connect } from 'react-redux';
import React from 'react';

class MyComponent extends React.Component {
  handleClick() {
    this.props.dispatch(routeActions.push('/user/account'));
  }

  render() {
    return (
      <div>
         <button onClick={ this.handleClick.bind(this) }>My button</button>
      </div>
    );
  }
}
export default connect()(MyComponent);
Leonel Machava
  • 1,501
  • 11
  • 19
  • definitely I am looking for that.. I have implemented `react-redux-router` and in my action when I do `getState()` I am getting its giving me `router` objeect but it does not have `transitionTo` function so I cannot route this . this is why I want to implement this approach.. In my store I have implemented `reduxReactRouter` too. Please can you elaborate this – gamer Feb 02 '16 at 10:55
  • I think I am missing something with `store` .. when I print `store` in the console its giving me `dispatch, setState, history` and so on functions – gamer Feb 02 '16 at 11:18
1

The answers above are correct, but fall appart when migrating to "Stateless Components" this quickly falls apart. My suggestion is using a higher-order function to take care of both the handling of preventing default click action and supplying the correct arguments. If you're already using ES2015 (through Babel for example), this could be this simple:

const preventDefault = (fn, ...args) => (e) => {
  e.preventDefault();
  fn(...args);
};

Then in your components call like so:

const Item = ({
  item,
  openItem
}) => (
  <div>
    <h1>{item.title}</h1>
    <a href="#" onClick={preventDefault(openItem, item)}>Open Item</a> // on click will call `openItem(item)`.
  </div>
)
Steven
  • 1,566
  • 2
  • 16
  • 38
  • Even though this method is not recommended on react github questions and on this question http://stackoverflow.com/questions/22639534/pass-props-to-parent-component-in-react-js but still when using redux and stateless components it becomes important that we are able to send component child back to some parent which is 4-5 links back in the chain. – Ishan Sharma Feb 10 '17 at 19:01