Bala
Bala

Reputation: 11244

Is it possible to have dynamic event handlers in React?

I have been told that its a very very bad practice but I am curious to know if it is possible to have dynamic handlers in React. Consider the code below. I would like to trigger appropriate handler based on props value. That is, when edit button is clicked edit handler is invoked etc. This is not working right now complaining that ...expected function but string provided...

import React from 'react';
import ReactDOM from 'react-dom';

export default class HelloWorld extends React.Component{
    render() {
        return(
        <div>
            <h4>Hello World</h4>
            <MyButton txt="edit" />
            <MyButton txt="insert" />
        </div>
        );
    }
};

export default class MyButton extends React.Component{
    edit() {
        console.log('edit button clicked');
    }
    insert() {
        console.log('insert button clicked');
    }
    render(){
        return (
            //Trigger handler based on this.props.txt
            <button onClick={this.props.txt}>{this.props.txt}</button>
        )
    }
}
ReactDOM.render(<HelloWorld/>, document.getElementById('hello'));

Upvotes: 2

Views: 1596

Answers (2)

Oleksandr T.
Oleksandr T.

Reputation: 77482

You get error because to onClick you should pass reference to function not String. In this case you can use bracket notation(this[this.props.txt]) to get property from object(MyButton)

class MyButton extends React.Component{
  edit(e) {
    console.log('edit button clicked', e);
  }

  insert(e) {
    console.log('insert button clicked', e);
  }

  render() {
    return <button 
      onClick={ this[this.props.txt] }
    >
      { this.props.txt }
    </button>
  }
}

Example

Upvotes: 1

Cithel
Cithel

Reputation: 696

What you ware trying to do in your code is not a bad practice, it is in fact known as "Controller View".

Flux applications have three major parts: the dispatcher, the stores, and the views (React components). These should not be confused with Model-View-Controller. Controllers do exist in a Flux application, but they are controller-views — views often found at the top of the hierarchy that retrieve data from the stores and pass this data down to their children. Additionally, action creators — dispatcher helper methods — are used to support a semantic API that describes all changes that are possible in the application. It can be useful to think of them as a fourth part of the Flux update cycle. https://facebook.github.io/flux/docs/overview.html

This allows you to create truly reusable components.

The error you get is because you are saying "on click, do "edit"", but you really want to say "on click, do edit()", and the edit function is a member of the class (so the this object). I don't have a project right know to test it, but replacing

<button onClick={this.props.txt}>{this.props.txt}</button>

By

<button onClick={this[this.props.txt}]>{this.props.txt}</button>

Should do the trick.

Upvotes: 1

Related Questions