Reputation: 11244
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
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>
}
}
Upvotes: 1
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