Arrow functions are an alternative way to define JavaScript functions. They provide a more compact function expression and reduce the programmer's keystrokes.
Note: Click here to learn about arrow functions in JavaScript.
In React, we use arrow functions as functional components, functions within class components, and event handlers.
We can use arrow functions to create functional components in React, just like regular functions.
Note: Click here to learn about React's functional components.
const App = () => { const user = 'Guest'; return ( <Message user={user} /> ); } const Message = ({user}) => { return <h1>Welcome {user}!</h1> } export default App;
We can make the code much cleaner for smaller components with only a single line of code.
const App = () => { const user = 'Guest'; return ( <Message user={user} /> ); } const Message = ({user}) => <h1>Welcome {user}!</h1> export default App;
We no longer have to write the {}
braces or the return
statement.
Using normal functions inside class components requires us to this
keyword in regular functions refers to the object calling the function. Hence, this
can refer to different objects in different situations. We can bind regular functions using the bind()
method to access the component's attributes using the this
keyword.
import {Component} from 'react'; const App = () => { const user = 'Guest'; return ( <Message user={user} /> ); } class Message extends Component { constructor(props) { super(props); this.state = {display: false}; this.handleClick = this.handleClick.bind(this); } handleClick() { this.setState({display: !this.state.display}); } render() { return ( <div> <button onClick={this.handleClick}>Click me!</button> {this.state.display && <h1>Welcome {this.props.user}!</h1>} </div> ); } }; export default App;
This example considers a simple web application that displays a welcome message when users click the button.
Message
component and pass it the name of the user we want to display. In this case, we want to display 'Guest'
.Message
.handleClick()
function. Doing so allows us to use the this
keyword without errors within the scope of handleClick()
.handleClick()
function. It toggles the display
property between true and false when it is called.handleClick()
function is called.display
property is true.With arrow functions, we can circumvent the need for binding. This is because the this
keyword in arrow functions refers to the object that defined the arrow function. When we define an arrow function within a class, this
will always refer to that class.
We can avoid explicit binding in one of two ways.
If we create the function as an arrow function, it automatically uses this
to refer to the class. In other words, we don't need to bind an arrow function.
import {Component} from 'react'; const App = () => { const user = 'Guest'; return ( <Message user={user} /> ); } class Message extends Component{ constructor(props) { super(props); this.state = {display: false}; } handleClick = () => this.setState({display: !this.state.display}); render() { return ( <div> <button onClick={this.handleClick}>Click me!</button> {this.state.display && <h1>Welcome {this.props.user}!</h1>} </div> ); } }; export default App;
On line 16, we create the handleClick()
function as an arrow function, hence we don't need to bind it.
render()
functionAlternatively, we can define the function normally but call it within render()
using an arrow function. Doing so makes the this
keyword refer to the class.
import {Component} from 'react'; const App = () => { const user = 'Guest'; return ( <Message user={user} /> ); } class Message extends Component{ constructor(props) { super(props); this.state = {display: false}; } handleClick() { this.setState({display: !this.state.display}); } render() { return ( <div> <button onClick={() => this.handleClick()}>Click me!</button> {this.state.display && <h1>Welcome {this.props.user}!</h1>} </div> ); } }; export default App;
In the above example, we define the handleClick()
function normally.
On line 22, we call the handleClick()
function using an arrow function.
Note: Creating arrow functions in the
render()
function creates a new function every time the component is rendered. For optimization concerns, the above method should be avoided when possible.
We can use the regular function calls within the render()
function (for class components) or return
statement (for functional components) to produce the 'too many re-renders'
error. This error means that the component is being rendered again and again, infinitely.
import {Component, useState} from 'react'; const App = () => { const user = 'Guest'; return ( <div> <Message user={user} /> </div> ); } const Message = ({user}) => { const [display, setDisplay] = useState(false); return ( <div> <button onClick={setDisplay(!display)}>Click me!</button> {display && <h1>Welcome {user}!</h1>} </div> ); }; export default App;
The terminal will not show any errors, but the output is a blank page. For closer inspection, we can open the browser's console (through inspect element or other means depending on the browser). There we can see the following error:
We can avoid this error by using an arrow function.
import {Component, useState} from 'react'; const App = () => { const user = 'Guest'; return ( <div> <Message user={user} /> </div> ); } const Message = ({user}) => { const [display, setDisplay] = useState(false); return ( <div> <button onClick={() => setDisplay(!display)}>Click me!</button> {display && <h1>Welcome {user}!</h1>} </div> ); }; export default App;
An arrow function prevents the setDisplay()
function from executing after the component is mounted. It onlys execute when users click the button.
Free Resources