React JS - What is a good way to handle click events?

I have a list containing about 2 thousand items. If I use onClick for each child, I get 2k listeners, which I currently have. I would like to do something like having the parent component listen for click events instead. But if I do this, I have no reference to the child component that I need to call setState. Also, the list of child components can be filtered dynamically (can using this.refs be bad?).

The best I can come up with is to have the hash identification of the id child components by the child components in the parent and look at the click view.

For illustrative purposes only:

var Parent = React.createClass({ shouldComponentUpdate: function() { return false; }, handler: function(e) { // look up from reference and set state }, componentWillUnmount: function() { // clean up reference }, render: function() { this.reference = {}; var items = []; for(var i = 0; i < this.props.items.length; i++) { var child = React.createClass(Child, {id: this.props.items[i].id}); items.push(child); reference[child.id] = child; } return React.createClass('div', {onClick: this.handler}, items); } }) 

I wonder if there is a way for React to handle this.

+5
source share
3 answers

A responsive way would be to use the Flux + Store manager. Basically, you can bind each item to an event that is fired from the store as soon as the store completes the tasks that you want to complete.

So the stream will be:

The element receives a clicked => event. Flux => is dispatched. The thread manager listens for events and performs the corresponding function with the data transferred from the Item component.

  var ItemStore = { doSomething: function(data){ // do something with the data } } MicroEvent.mixin(ItemStore); var AppDispatcher = new Dispatcher(); AppDispatcher.register(function(payload) { switch (payload.eventName) { case 'item-clicked': ItemStore.doSomething(payload.data.someData); ItemStore.trigger('did-something'); } return true; }) var Item = React.createClass({ shouldComponentUpdate: function() { return false; }, componentDidMount: function() { ItemStore.bind('did-something', this.submitHandled); }, handler: function(e) { AppDispatcher.dispatch({ eventName: 'item-clicked', data: { someData: 'sample data' } }); }, componentWillUnmount: function() { // clean up reference }, submitHandled: function() { // do something after the click }, render: function() { // insert your item html here. } }) 
+1
source

I think this answer might help ... It doesn't matter if you have 2000 event handlers or just one. Reacts with him the same. Remember that the HTML that you return to your rendering method is not added to the DOM, but it is just used by React to create a virtual DOM representation. In the end, React has only one onClick.

Respond in an efficient way to bind events to many dom elements

If you need to know which element was triggered by a click, you just need to access event.target and use any data attribute to identify the element with a click.

+3
source

Based on @damianmr answer, here is an example .

 var Child = React.createClass({ shouldComponentUpdate(nextProps){ if (this.props.text !== nextProps.text) return true; if (this.props.active !== nextProps.active) return true; return false; }, render(){ var className = 'Child'; if (this.props.active) className += ' Child-active'; return ( <div {...this.props} className={className}> {this.props.text} </div> ); } }); 
 var Parent = React.createClass({ getInitialState(){ return {active: -1}; }, setActive(id){ this.setState({active: id}); }, render(){ return ( <div> {this.props.items.map((item) => { return ( <Child active={this.state.active === item.id} onClick={() => this.setActive(item.id)} text={'My id is ' + item.id} key={item.id} /> ); })} </div> ); } }); 
+1
source

All Articles