React JS onClick event handler

React JS onClick event handler



I have


var TestApp = React.createClass(
getComponent: function()
console.log(this.props);
,
render: function()
return(
<div>
<ul>
<li onClick=this.getComponent>Component 1</li>
</ul>
</div>
);

);
React.renderComponent(<TestApp />, document.body);



I want to color the background of the clicked list element. How can I do this in React ?



Something like


$('li').on('click', function()
$(this).css('background-color': '#ccc');
);




9 Answers
9



Why not just:


onItemClick: function (event)

event.currentTarget.style.backgroundColor = '#ccc';

,

render: function()
return (
<div>
<ul>
<li onClick=this.onItemClick>Component 1</li>
</ul>
</div>
);



And if you want to be more React-ive about it, you might want to set the selected item as state of its containing React component, then reference that state to determine the item's color within render:


render


onItemClick: function (event)

this.setState( selectedItem: event.currentTarget.dataset.id );
//where 'id' = whatever suffix you give the data-* li attribute
,

render: function()
return (
<div>
<ul>
<li onClick=this.onItemClick data-id="1" className=this.state.selectedItem == 1 ? "on" : "off">Component 1</li>
<li onClick=this.onItemClick data-id="2" className=this.state.selectedItem == 2 ? "on" : "off">Component 2</li>
<li onClick=this.onItemClick data-id="3" className=this.state.selectedItem == 3 ? "on" : "off">Component 3</li>
</ul>
</div>
);
,



Of course, you'd want to put those <li>s into a loop, and you need to make the li.on and li.off styles set your background-color.


<li>


li.on


li.off


background-color





+1 this is particularly useful for large lists of elements that require click handlers since you don't need to create a new function every time one of them is rendered.
– Zach
Dec 26 '16 at 22:43



Two ways I can think of are


var TestApp = React.createClass(
getComponent: function(index)
$(this.getDOMNode()).find('li:nth-child(' + index + ')').css(
'background-color': '#ccc'
);
,
render: function()
return (
<div>
<ul>
<li onClick=this.getComponent.bind(this, 1)>Component 1</li>
<li onClick=this.getComponent.bind(this, 2)>Component 2</li>
<li onClick=this.getComponent.bind(this, 3)>Component 3</li>
</ul>
</div>
);

);
React.renderComponent(<TestApp /> , document.getElementById('soln1'));



This is my personal favorite.


var ListItem = React.createClass(
getInitialState: function()
return
isSelected: false
;
,
handleClick: function()
this.setState(
isSelected: true
)
,
render: function()
var isSelected = this.state.isSelected;
var style =
'background-color': ''
;
if (isSelected)
style =
'background-color': '#ccc'
;

return (
<li onClick=this.handleClick style=style>this.props.content</li>
);

);

var TestApp2 = React.createClass(
getComponent: function(index)
$(this.getDOMNode()).find('li:nth-child(' + index + ')').css(
'background-color': '#ccc'
);
,
render: function()
return (
<div>
<ul>
<ListItem content="Component 1" />
<ListItem content="Component 2" />
<ListItem content="Component 3" />
</ul>
</div>
);

);
React.renderComponent(<TestApp2 /> , document.getElementById('soln2'));



Here is a DEMO



I hope this helps.





It sure helped me. Thanks!
– Monica
Feb 23 '17 at 18:15





It's not recommended to apply the bind within the render function since it will do it every time the component is rendered. you can move it to some function which runs at the start of the lifecycle
– jony89
Apr 30 '17 at 14:44





@jony89 agreed if .bind doesn't take an extra parameter. But in the first case it does. I don't think there is another way
– Dhiraj
Apr 30 '17 at 17:44



.bind





There is, create three different functions (which created by the result of getComponent.bind(this, 1)), though that definite can be a decision (would do it for 2-3 components, not for 20 - unless it's really performance issue and easy to create it dynamically).
– jony89
May 1 '17 at 18:25




Here is how you define a react onClick event handler, which was answering the question title... using es6 syntax


import React, Component from 'react';

export default class Test extends Component
handleClick(e)
e.preventDefault()
console.log(e.target)


render()
return (
<a href='#' onClick=e => this.handleClick(e)>click me</a>
)






Neither bind nor arrow functions should be used within render methods because they result in a new function being created each time. This has the effect changing the component's state, and components with changed state are always re-rendered. For a single a this is no big deal. For generated lists with clickable items this becomes a big deal very quickly. This is why it's specifically warned against.
– hippietrail
Sep 23 '17 at 2:16


bind


render


a



Use ECMA2015. Arrow functions make "this" a lot more intuitive.


import React from 'react';


class TestApp extends React.Component
getComponent(e, index)
$(e.target).css(
'background-color': '#ccc'
);

render()
return (
<div>
<ul>
<li onClick=(e) => this.getComponent(e, 1)>Component 1</li>
<li onClick=(e) => this.getComponent(e, 2)>Component 2</li>
<li onClick=(e) => this.getComponent(e, 3)>Component 3</li>
</ul>
</div>
);

);
React.renderComponent(<TestApp /> , document.getElementById('soln1'));`





index doesn't do anything here?
– northamerican
Oct 11 '16 at 17:13


index





@northamerican - Nope, it's just there to add some parameter clarity
– itcropper
Oct 16 '16 at 21:52





This actually is bad for performance as it creates a new function upon each render. See: stackoverflow.com/questions/36677733/…
– Jochie Nabuurs
Sep 15 '17 at 10:24



If you're using ES6, here's some simple example code:


import React from 'wherever_react_is';

class TestApp extends React.Component

getComponent(event)
console.log('li item clicked!');
event.currentTarget.style.backgroundColor = '#ccc';


render()
return(
<div>
<ul>
<li onClick=this.getComponent.bind(this)>Component 1</li>
</ul>
</div>
);



export default TestApp;



In ES6 class bodies, functions no longer require the 'function' keyword and they don't need to be separated by commas. You can also use the => syntax as well if you wish.



Here's an example with dynamically created elements:


import React from 'wherever_react_is';

class TestApp extends React.Component

constructor(props)
super(props);

this.state =
data: [
name: 'Name 1', id: 123,
name: 'Name 2', id: 456
]



getComponent(event)
console.log('li item clicked!');
event.currentTarget.style.backgroundColor = '#ccc';


render()
<div>
<ul>
this.state.data.map(d =>
return(
<li key=d.id onClick=this.getComponent.bind(this)>d.name</li>
)
)
</ul>
</div>
);



export default TestApp;



Note that each dynamically created element should have a unique reference 'key'.



Furthermore, if you would like to pass the actual data object (rather than the event) into your onClick function, you will need to pass that into your bind. For example:



New onClick function:


getComponent(object)
console.log(object.name);



Passing in the data object:


this.state.data.map(d =>
return(
<li key=d.id onClick=this.getComponent.bind(this, d)>d.name</li>
)
)





I am trying to build my li items dynamic and then this sees to become undefined and the onClick function therefore throws an error.
– landed
Feb 23 '16 at 21:13





I just found a similar answer where you need to use .bind(this)); at the end of the anonymous function as this here refers to window until you make the bind...
– landed
Feb 23 '16 at 22:01





For dynamically created elements you're right - i've updated the answer to cater for this scenario. Thanks.
– dirtigr00vz
Feb 24 '16 at 10:33





This should be the answer. I was specifically missing the (this, d) part.
– mjwrazor
Oct 23 '16 at 16:25





No, you should never use bind or arrow functions in JSX.
– hippietrail
Sep 23 '17 at 2:18


bind



Handling events with React elements is very similar to handling events
on DOM elements. There are some syntactic differences:



So as mentioned in React documentation, they quite similar to normal HTML when it comes to Event Handling, but event names in React using camelcase, because they are not really HTML, they are JavaScript, also, you pass the function while we passing function call in a string format for HTML, they are different, but the concepts are pretty similar...



Look at the example below, pay attention to the way event get passed to the function:


function ActionLink()
function handleClick(e)
e.preventDefault();
console.log('The link was clicked.');


return (
<a href="#" onClick=handleClick>
Click me
</a>
);



You can make use of the React.createClone method. Create your element, than create a clone of it. During the clone's creation, you can inject props. Inject an onClick : method prop like this



onClick : () => this.changeColor(originalElement, index)


onClick : () => this.changeColor(originalElement, index)



the changeColor method will set the state with the duplicate, allowing you sto set the color in the process.




render()

return(
<ul>

this.state.items.map((val, ind) =>
let item = <li key=ind>val</li>;
let props =
onClick: () => this.Click(item, ind),
key : ind,
ind

let clone = React.cloneElement(item, props, [val]);
return clone;
)

</ul>
)




import React from 'react';

class MyComponent extends React.Component

getComponent(event)
event.target.style.backgroundColor = '#ccc';

// or you can write
//arguments[0].target.style.backgroundColor = '#ccc';


render()
return(
<div>
<ul>
<li onClick=this.getComponent.bind(this)>Component 1</li>
</ul>
</div>
);



export MyComponent ; // use this to be possible in future imports with like: import MyComponent from './MyComponent'
export default MyComponent;





This seems essentially identical to the 11 point answer, and resurrects a pretty-or question-why?
– Dave Newton
2 days ago



Please comment if you downvote. This is a non-standard (but not so uncommon) React pattern that doesn't use JSX, instead putting everything inline. Also, it's Coffeescript.



The 'React-way' to do this would be with the component's own state:



(c = console.log.bind console)


c = console.log.bind console


mock_items: [

name: 'item_a'
uid: shortid()


name: 'item_b'
uid: shortid()


name: 'item_c'
uid: shortid()

]
getInitialState: ->
lighted_item: null
render: ->
div null,
ul null,
for item, idx in @mock_items
uid = item.uid
li
key: uid
onClick: do (idx, uid) =>
(e) =>
# justf to illustrate these are bound in closure by the do lambda,
c idx
c uid
@setState
lighted_item: uid
style:
cursor: 'pointer'
background: do (uid) =>
c @state.lighted_item
c 'and uid', uid
if @state.lighted_item is uid then 'magenta' else 'chartreuse'
# background: 'chartreuse'
item.name



This example works -- I tested it locally.
You can check out this example code exactly at my github.
Originally the env was only local for my own whiteboard r&d purposes but I posted it to Github for this. It may get written over at some point but you can check out the commit from Sept 8, 2016 to see this.



More generally, if you want to see how this CS/no-JSX pattern for React works, check out some recent work here. It's possible I will have time to fully implement a POC for this app idea, the stack for which includes NodeJS, Primus, Redis, & React.





the background need not be a do lambda: This expression works also: background: if @state.lighted_item is uid then 'magenta' else 'chartreuse'
– Wylie Kulik
Sep 8 '16 at 13:38


do


background: if @state.lighted_item is uid then 'magenta' else 'chartreuse'





hello how can i view onclick on browser console?
– Muneem Habib
Nov 25 '16 at 19:33





Why would you use CoffeeScript in an answer to a question that doesn't mention it in any way? It doesn't make any sense and it can probably make the answer harder to read for the asker, as he might not know/like CoffeeScript. Downvoting, obviously.
– macbem
Mar 7 '17 at 21:55





No but it is something built on top of the language, is absolutelty not standard and requires installing, and compiling. it was a truly a poor choice to write your answer in coffeescript when there is ZERO hinting at all that they are using coffeescript in their project
– TheRealMrCrowley
Mar 15 '17 at 6:54





Coffeescript is just a layer on top of js. FTFY.
– machineghost
May 9 '17 at 23:42






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

ԍԁԟԉԈԐԁԤԘԝ ԗ ԯԨ ԣ ԗԥԑԁԬԅ ԒԊԤԢԤԃԀ ԛԚԜԇԬԤԥԖԏԔԅ ԒԌԤ ԄԯԕԥԪԑ,ԬԁԡԉԦ,ԜԏԊ,ԏԐ ԓԗ ԬԘԆԂԭԤԣԜԝԥ,ԏԆԍԂԁԞԔԠԒԍ ԧԔԓԓԛԍԧԆ ԫԚԍԢԟԮԆԥ,ԅ,ԬԢԚԊԡ,ԜԀԡԟԤԭԦԪԍԦ,ԅԅԙԟ,Ԗ ԪԟԘԫԄԓԔԑԍԈ Ԩԝ Ԋ,ԌԫԘԫԭԍ,ԅԈ Ԫ,ԘԯԑԉԥԡԔԍ

How to change the default border color of fbox? [duplicate]

Henj