Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass an event handler to a child component in React

I have a <Button /> component I've created in React that abstracts out some of the styling in my application. I am using it in two different contexts - one to submit a login form, and the other to navigate to the registration page (and probably other contexts in the future).

I am trying to figure out how to pass the event handlers from the parent component to the <Button />. I want to call an onSubmit handler for the login form, but an onClick handler for the navigation button. Is this possible?

I have tried calling the component like this:

<Button text={callToAction} style={styles.callToActionButton} onClick={() => FlowRouter.go("Auth")}/>

<Button text="Go!" style={styles.registerButton} onSubmit={() => this.register(this.state.user, this.state.password)}/>

I've also tried removing the arrow function, which just causes the functions to execute when the component is loaded:

// executes event handlers on page load
<Button text={callToAction} style={styles.callToActionButton} onClick={FlowRouter.go("Auth")}/>

<Button text="Go!" style={styles.registerButton} onSubmit={this.register(this.state.user, this.state.password)}/>
like image 563
bgmaster Avatar asked Oct 06 '16 20:10

bgmaster


People also ask

How can you pass event handler to component?

Passing Event Handler to Subcomponent The Address component is using the destructuring assignment { type, houseNo, clickHandler } to access the passed prop values directly. The clickHandler is a function to handle clicks, which is being passed to the onClick attribute.

How do you emit event from parent to child in react?

To pass data from child to parent component in React: Pass a function as a prop to the Child component. Call the function in the Child component and pass the data as arguments. Access the data in the function in the Parent .


2 Answers

In general, you can forward the onClick handler to your button class by passing it as a property. You could this make a required prop by simply defining the propTypes for your button component.

As an example, I added a small snippet that shows how it works

var StyledButton = React.createClass({
  propTypes: {
    // the StyledButton requires a clickHandler
    clickHandler: React.PropTypes.func.Required,
    // and I guess the text can be seen as required as well
    text: React.PropTypes.string.required
  },
  render: function() {
    // as you are sure you have a clickHandler, you can just reference it directly from the props
    return <button type="button" onClick={this.props.clickHandler}>{this.props.text}</button>;
  }
});

var MyForm = React.createClass({
  getInitialState() {
    return {
      clicked: 0
    };
  },
  click() {
    this.setState({clicked: this.state.clicked+1});
  	alert('ouch');
  },
  secondClickHandler() {
    this.setState({clicked: 0});
    alert(':(');
  },
  render() {
    // your parent component simply sets which button  
    return <fieldset>
        <div>
    	  <StyledButton clickHandler={this.click} text="Click me" /> 
          { (this.state.clicked > 0) && <StyledButton clickHandler={this.secondClickHandler} text="Not again" /> }
        </div>
    </fieldset>;
  }
});

ReactDOM.render(
  <MyForm />,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.min.js"></script>
<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

Also, you wouldn't in general use the submit method of a button, you would rather send the data received to a webservice, and handle any changes when the result is received. The submit kills the current website and needs to load everything anew, while with an ajax call, or a store, it can just wait for the result and then redirect the user based on the response

like image 187
Icepickle Avatar answered Oct 19 '22 18:10

Icepickle


How we have handled this is we have a button component that renders an a tag and then we have a href prop and a onClick prop you can pass in. If its a link just pass in the href prop to the button and if you are wanting it to execute a function just pass it in an onClick prop and make sure it gets set on the a tag.

In the Button component we also setup a custom onClick function that looks like this:

_onClick: function(e) {
  if (!this.props.onClick) {
    return; 
  }
  this.props.onClick(e);
}

and then on the a tag

<a href={this.props.href} onClick={this._onClick} />
like image 45
finalfreq Avatar answered Oct 19 '22 19:10

finalfreq