Related
I have been reading a bunch of React code and I see stuff like this that I don't understand:
handleChange = field => e => {
e.preventDefault();
/// Do something here
}
That is a curried function
First, examine this function with two parameters …
const add = (x, y) => x + y
add(2, 3) //=> 5
Here it is again in curried form …
const add = x => y => x + y
Here is the same1 code without arrow functions …
const add = function (x) {
return function (y) {
return x + y
}
}
Focus on return
It might help to visualize it another way. We know that arrow functions work like this – let's pay particular attention to the return value.
const f = someParam => returnValue
So our add function returns a function – we can use parentheses for added clarity. The bolded text is the return value of our function add
const add = x => (y => x + y)
In other words add of some number returns a function
add(2) // returns (y => 2 + y)
Calling curried functions
So in order to use our curried function, we have to call it a bit differently …
add(2)(3) // returns 5
This is because the first (outer) function call returns a second (inner) function. Only after we call the second function do we actually get the result. This is more evident if we separate the calls on two lines …
const add2 = add(2) // returns function(y) { return 2 + y }
add2(3) // returns 5
Applying our new understanding to your code
related: ”What’s the difference between binding, partial application, and currying?”
OK, now that we understand how that works, let's look at your code
handleChange = field => e => {
e.preventDefault()
/// Do something here
}
We'll start by representing it without using arrow functions …
handleChange = function(field) {
return function(e) {
e.preventDefault()
// Do something here
// return ...
};
};
However, because arrow functions lexically bind this, it would actually look more like this …
handleChange = function(field) {
return function(e) {
e.preventDefault()
// Do something here
// return ...
}.bind(this)
}.bind(this)
Maybe now we can see what this is doing more clearly. The handleChange function is creating a function for a specified field. This is a handy React technique because you're required to setup your own listeners on each input in order to update your applications state. By using the handleChange function, we can eliminate all the duplicated code that would result in setting up change listeners for each field. Cool!
1 Here I did not have to lexically bind this because the original add function does not use any context, so it is not important to preserve it in this case.
Even more arrows
More than two arrow functions can be sequenced, if necessary -
const three = a => b => c =>
a + b + c
const four = a => b => c => d =>
a + b + c + d
three (1) (2) (3) // 6
four (1) (2) (3) (4) // 10
Curried functions are capable of surprising things. Below we see $ defined as a curried function with two parameters, yet at the call site, it appears as though we can supply any number of arguments. Currying is the abstraction of arity -
const $ = x => k =>
$ (k (x))
const add = x => y =>
x + y
const mult = x => y =>
x * y
$ (1) // 1
(add (2)) // + 2 = 3
(mult (6)) // * 6 = 18
(console.log) // 18
$ (7) // 7
(add (1)) // + 1 = 8
(mult (8)) // * 8 = 64
(mult (2)) // * 2 = 128
(mult (2)) // * 2 = 256
(console.log) // 256
Partial application
Partial application is a related concept. It allows us to partially apply functions, similar to currying, except the function does not have to be defined in curried form -
const partial = (f, ...a) => (...b) =>
f (...a, ...b)
const add3 = (x, y, z) =>
x + y + z
partial (add3) (1, 2, 3) // 6
partial (add3, 1) (2, 3) // 6
partial (add3, 1, 2) (3) // 6
partial (add3, 1, 2, 3) () // 6
partial (add3, 1, 1, 1, 1) (1, 1, 1, 1, 1) // 3
Here's a working demo of partial you can play with in your own browser -
const partial = (f, ...a) => (...b) =>
f (...a, ...b)
const preventDefault = (f, event) =>
( event .preventDefault ()
, f (event)
)
const logKeypress = event =>
console .log (event.which)
document
.querySelector ('input[name=foo]')
.addEventListener ('keydown', partial (preventDefault, logKeypress))
<input name="foo" placeholder="type here to see ascii codes" size="50">
Briefly
It is a function that returns another function written in a short way.
const handleChange = field => e => {
e.preventDefault()
// Do something here
}
// is equal to
function handleChange(field) {
return function(e) {
e.preventDefault()
// Do something here
}
}
Motivation
This technique can be utilized in a scenario where we have a callback function with fixed parameters, but we need to pass additional variables while avoiding global variables.
For instance, we have a button that has an onClick callback, and we want to pass a variable, such as id, but onClick accepts a single argument, event, making it impossible to pass id along with event.
const handleClick = (event, id) {
event.preventDefault()
// Dispatch some delete action by passing record `id`
}
It is not going to work.
Here as a solution, we write a function that returns another function with id in its variables scope without using any global variables:
const handleClick = id => event {
event.preventDefault()
// Dispatch some delete action by passing record `id`
}
const Confirm = props => (
<div>
<h1>Are you sure to delete?</h1>
<button onClick={handleClick(props.id)}>
Delete
</button>
</div
)
Function composition
Multiple arrow functions also are called "curried functions" and are used for function compositions.
import {compose} from 'redux'
import {store} from './store.js'
const pickSelectedUser = props => {
const {selectedName, users} = props
const foundUser = users.find(user => user.name === selectedName)
return foundUser.id
}
const deleteUser = userId => event => {
event.preventDefault()
store.dispatch({
type: `DELETE_USER`,
userId,
})
}
// The compose function creates a new function that accepts a parameter.
// The parameter will be passed throw the functions from down to top.
// Each function will change the value and pass it to the next function
// By changing value it was not meant a mutation
const handleClick = compose(
deleteUser,
pickSelectedUser,
)
const Confirm = props => (
<div>
<h1>Are you sure to delete?</h1>
<button onClick={handleClick(props)}>
Delete
</button>
</div
)
A general tip: If you get confused by any of new JavaScript syntax and how it will compile, you can check Babel. For example, copying your code in Babel and selecting the ES 2015 preset will give an output like this
handleChange = function handleChange(field) {
return function (e) {
e.preventDefault();
// Do something here
};
};
Understanding the available syntaxes of arrow functions will give you an understanding of what behaviour they are introducing when 'chained' like in the examples you provided.
When an arrow function is written without block braces, with or without multiple parameters, the expression that constitutes the function's body is implicitly returned. In your example, that expression is another arrow function.
No arrow funcs Implicitly return `e=>{…}` Explicitly return `e=>{…}`
---------------------------------------------------------------------------------
function (field) { | field => e => { | field => {
return function (e) { | | return e => {
e.preventDefault() | e.preventDefault() | e.preventDefault()
} | | }
} | } | }
Another advantage of writing anonymous functions using the arrow syntax is that they are bound lexically to the scope in which they are defined. From 'Arrow functions' on MDN:
An arrow function expression has a shorter syntax compared to function expressions and lexically binds the this value. Arrow functions are always anonymous.
This is particularly pertinent in your example considering that it is taken from a reactjs application. As as pointed out by #naomik, in React you often access a component's member functions using this. For example:
Unbound Explicitly bound Implicitly bound
------------------------------------------------------------------------------
function (field) { | function (field) { | field => e => {
return function (e) { | return function (e) { |
this.setState(...) | this.setState(...) | this.setState(...)
} | }.bind(this) |
} | }.bind(this) | }
Think of it like this, every time you see a arrow, you replace it with function.function parameters are defined before the arrow.
So in your example:
field => // function(field){}
e => { e.preventDefault(); } // function(e){e.preventDefault();}
and then together:
function (field) {
return function (e) {
e.preventDefault();
};
}
From the docs:
// Basic syntax:
(param1, param2, paramN) => { statements }
(param1, param2, paramN) => expression
// equivalent to: => { return expression; }
// Parentheses are optional when there's only one argument:
singleParam => { statements }
singleParam => expression
It might be not totally related, but since the question mentioned react uses case (and I keep bumping into this SO thread): There is one important aspect of the double arrow function which is not explicitly mentioned here.
Only the 'first' arrow(function) gets named (and thus 'distinguishable' by the run-time), any following arrows are anonymous and from React point of view count as a 'new' object on every render.
Thus double arrow function will cause any PureComponent to rerender all the time.
Example
You have a parent component with a change handler as:
handleChange = task => event => { ... operations which uses both task and event... };
and with a render like:
{
tasks.map(task => <MyTask handleChange={this.handleChange(task)}/>
}
handleChange then used on an input or click. And this all works and looks very nice. BUT it means that any change that will cause the parent to rerender (like a completely unrelated state change) will also re-render ALL of your MyTask as well even though they are PureComponents.
This can be alleviated many ways such as passing the 'outmost' arrow and the object you would feed it with or writing a custom shouldUpdate function or going back to basics such as writing named functions (and binding the this manually...)
The example in your question is that of a curried function which makes use of arrow function and has an implicit return for the first argument.
Arrow function lexically bind this i.e they do not have their own this argument but take the this value from the enclosing scope
An equivalent of the above code would be
const handleChange = (field) {
return function(e) {
e.preventDefault();
/// Do something here
}.bind(this);
}.bind(this);
One more thing to note about your example is that define handleChange as a const or a function. Probably you are using it as part of a class method and it uses a class fields syntax
so instead of binding the outer function directly, you would bind it in the class constructor
class Something{
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(field) {
return function(e) {
e.preventDefault();
// do something
}
}
}
Another thing to note in the example is the difference between implicit and explicit return.
const abc = (field) => field * 2;
Above is an example of implicit return ie. it takes the value field as argument and returns the result field*2 which explicitly specifying the function to return
For an explicit return you would explicitly tell the method to return the value
const abc = () => { return field*2; }
Another thing to note about arrow functions is that they do not have their own arguments but inherit that from the parents scope as well.
For example if you just define an arrow function like
const handleChange = () => {
console.log(arguments) // would give an error on running since arguments in undefined
}
As an alternative arrow functions provide the rest parameters that you can use
const handleChange = (...args) => {
console.log(args);
}
I have been reading a bunch of React code and I see stuff like this that I don't understand:
handleChange = field => e => {
e.preventDefault();
/// Do something here
}
That is a curried function
First, examine this function with two parameters …
const add = (x, y) => x + y
add(2, 3) //=> 5
Here it is again in curried form …
const add = x => y => x + y
Here is the same1 code without arrow functions …
const add = function (x) {
return function (y) {
return x + y
}
}
Focus on return
It might help to visualize it another way. We know that arrow functions work like this – let's pay particular attention to the return value.
const f = someParam => returnValue
So our add function returns a function – we can use parentheses for added clarity. The bolded text is the return value of our function add
const add = x => (y => x + y)
In other words add of some number returns a function
add(2) // returns (y => 2 + y)
Calling curried functions
So in order to use our curried function, we have to call it a bit differently …
add(2)(3) // returns 5
This is because the first (outer) function call returns a second (inner) function. Only after we call the second function do we actually get the result. This is more evident if we separate the calls on two lines …
const add2 = add(2) // returns function(y) { return 2 + y }
add2(3) // returns 5
Applying our new understanding to your code
related: ”What’s the difference between binding, partial application, and currying?”
OK, now that we understand how that works, let's look at your code
handleChange = field => e => {
e.preventDefault()
/// Do something here
}
We'll start by representing it without using arrow functions …
handleChange = function(field) {
return function(e) {
e.preventDefault()
// Do something here
// return ...
};
};
However, because arrow functions lexically bind this, it would actually look more like this …
handleChange = function(field) {
return function(e) {
e.preventDefault()
// Do something here
// return ...
}.bind(this)
}.bind(this)
Maybe now we can see what this is doing more clearly. The handleChange function is creating a function for a specified field. This is a handy React technique because you're required to setup your own listeners on each input in order to update your applications state. By using the handleChange function, we can eliminate all the duplicated code that would result in setting up change listeners for each field. Cool!
1 Here I did not have to lexically bind this because the original add function does not use any context, so it is not important to preserve it in this case.
Even more arrows
More than two arrow functions can be sequenced, if necessary -
const three = a => b => c =>
a + b + c
const four = a => b => c => d =>
a + b + c + d
three (1) (2) (3) // 6
four (1) (2) (3) (4) // 10
Curried functions are capable of surprising things. Below we see $ defined as a curried function with two parameters, yet at the call site, it appears as though we can supply any number of arguments. Currying is the abstraction of arity -
const $ = x => k =>
$ (k (x))
const add = x => y =>
x + y
const mult = x => y =>
x * y
$ (1) // 1
(add (2)) // + 2 = 3
(mult (6)) // * 6 = 18
(console.log) // 18
$ (7) // 7
(add (1)) // + 1 = 8
(mult (8)) // * 8 = 64
(mult (2)) // * 2 = 128
(mult (2)) // * 2 = 256
(console.log) // 256
Partial application
Partial application is a related concept. It allows us to partially apply functions, similar to currying, except the function does not have to be defined in curried form -
const partial = (f, ...a) => (...b) =>
f (...a, ...b)
const add3 = (x, y, z) =>
x + y + z
partial (add3) (1, 2, 3) // 6
partial (add3, 1) (2, 3) // 6
partial (add3, 1, 2) (3) // 6
partial (add3, 1, 2, 3) () // 6
partial (add3, 1, 1, 1, 1) (1, 1, 1, 1, 1) // 3
Here's a working demo of partial you can play with in your own browser -
const partial = (f, ...a) => (...b) =>
f (...a, ...b)
const preventDefault = (f, event) =>
( event .preventDefault ()
, f (event)
)
const logKeypress = event =>
console .log (event.which)
document
.querySelector ('input[name=foo]')
.addEventListener ('keydown', partial (preventDefault, logKeypress))
<input name="foo" placeholder="type here to see ascii codes" size="50">
Briefly
It is a function that returns another function written in a short way.
const handleChange = field => e => {
e.preventDefault()
// Do something here
}
// is equal to
function handleChange(field) {
return function(e) {
e.preventDefault()
// Do something here
}
}
Motivation
This technique can be utilized in a scenario where we have a callback function with fixed parameters, but we need to pass additional variables while avoiding global variables.
For instance, we have a button that has an onClick callback, and we want to pass a variable, such as id, but onClick accepts a single argument, event, making it impossible to pass id along with event.
const handleClick = (event, id) {
event.preventDefault()
// Dispatch some delete action by passing record `id`
}
It is not going to work.
Here as a solution, we write a function that returns another function with id in its variables scope without using any global variables:
const handleClick = id => event {
event.preventDefault()
// Dispatch some delete action by passing record `id`
}
const Confirm = props => (
<div>
<h1>Are you sure to delete?</h1>
<button onClick={handleClick(props.id)}>
Delete
</button>
</div
)
Function composition
Multiple arrow functions also are called "curried functions" and are used for function compositions.
import {compose} from 'redux'
import {store} from './store.js'
const pickSelectedUser = props => {
const {selectedName, users} = props
const foundUser = users.find(user => user.name === selectedName)
return foundUser.id
}
const deleteUser = userId => event => {
event.preventDefault()
store.dispatch({
type: `DELETE_USER`,
userId,
})
}
// The compose function creates a new function that accepts a parameter.
// The parameter will be passed throw the functions from down to top.
// Each function will change the value and pass it to the next function
// By changing value it was not meant a mutation
const handleClick = compose(
deleteUser,
pickSelectedUser,
)
const Confirm = props => (
<div>
<h1>Are you sure to delete?</h1>
<button onClick={handleClick(props)}>
Delete
</button>
</div
)
A general tip: If you get confused by any of new JavaScript syntax and how it will compile, you can check Babel. For example, copying your code in Babel and selecting the ES 2015 preset will give an output like this
handleChange = function handleChange(field) {
return function (e) {
e.preventDefault();
// Do something here
};
};
Understanding the available syntaxes of arrow functions will give you an understanding of what behaviour they are introducing when 'chained' like in the examples you provided.
When an arrow function is written without block braces, with or without multiple parameters, the expression that constitutes the function's body is implicitly returned. In your example, that expression is another arrow function.
No arrow funcs Implicitly return `e=>{…}` Explicitly return `e=>{…}`
---------------------------------------------------------------------------------
function (field) { | field => e => { | field => {
return function (e) { | | return e => {
e.preventDefault() | e.preventDefault() | e.preventDefault()
} | | }
} | } | }
Another advantage of writing anonymous functions using the arrow syntax is that they are bound lexically to the scope in which they are defined. From 'Arrow functions' on MDN:
An arrow function expression has a shorter syntax compared to function expressions and lexically binds the this value. Arrow functions are always anonymous.
This is particularly pertinent in your example considering that it is taken from a reactjs application. As as pointed out by #naomik, in React you often access a component's member functions using this. For example:
Unbound Explicitly bound Implicitly bound
------------------------------------------------------------------------------
function (field) { | function (field) { | field => e => {
return function (e) { | return function (e) { |
this.setState(...) | this.setState(...) | this.setState(...)
} | }.bind(this) |
} | }.bind(this) | }
Think of it like this, every time you see a arrow, you replace it with function.function parameters are defined before the arrow.
So in your example:
field => // function(field){}
e => { e.preventDefault(); } // function(e){e.preventDefault();}
and then together:
function (field) {
return function (e) {
e.preventDefault();
};
}
From the docs:
// Basic syntax:
(param1, param2, paramN) => { statements }
(param1, param2, paramN) => expression
// equivalent to: => { return expression; }
// Parentheses are optional when there's only one argument:
singleParam => { statements }
singleParam => expression
It might be not totally related, but since the question mentioned react uses case (and I keep bumping into this SO thread): There is one important aspect of the double arrow function which is not explicitly mentioned here.
Only the 'first' arrow(function) gets named (and thus 'distinguishable' by the run-time), any following arrows are anonymous and from React point of view count as a 'new' object on every render.
Thus double arrow function will cause any PureComponent to rerender all the time.
Example
You have a parent component with a change handler as:
handleChange = task => event => { ... operations which uses both task and event... };
and with a render like:
{
tasks.map(task => <MyTask handleChange={this.handleChange(task)}/>
}
handleChange then used on an input or click. And this all works and looks very nice. BUT it means that any change that will cause the parent to rerender (like a completely unrelated state change) will also re-render ALL of your MyTask as well even though they are PureComponents.
This can be alleviated many ways such as passing the 'outmost' arrow and the object you would feed it with or writing a custom shouldUpdate function or going back to basics such as writing named functions (and binding the this manually...)
The example in your question is that of a curried function which makes use of arrow function and has an implicit return for the first argument.
Arrow function lexically bind this i.e they do not have their own this argument but take the this value from the enclosing scope
An equivalent of the above code would be
const handleChange = (field) {
return function(e) {
e.preventDefault();
/// Do something here
}.bind(this);
}.bind(this);
One more thing to note about your example is that define handleChange as a const or a function. Probably you are using it as part of a class method and it uses a class fields syntax
so instead of binding the outer function directly, you would bind it in the class constructor
class Something{
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(field) {
return function(e) {
e.preventDefault();
// do something
}
}
}
Another thing to note in the example is the difference between implicit and explicit return.
const abc = (field) => field * 2;
Above is an example of implicit return ie. it takes the value field as argument and returns the result field*2 which explicitly specifying the function to return
For an explicit return you would explicitly tell the method to return the value
const abc = () => { return field*2; }
Another thing to note about arrow functions is that they do not have their own arguments but inherit that from the parents scope as well.
For example if you just define an arrow function like
const handleChange = () => {
console.log(arguments) // would give an error on running since arguments in undefined
}
As an alternative arrow functions provide the rest parameters that you can use
const handleChange = (...args) => {
console.log(args);
}
I have been reading a bunch of React code and I see stuff like this that I don't understand:
handleChange = field => e => {
e.preventDefault();
/// Do something here
}
That is a curried function
First, examine this function with two parameters …
const add = (x, y) => x + y
add(2, 3) //=> 5
Here it is again in curried form …
const add = x => y => x + y
Here is the same1 code without arrow functions …
const add = function (x) {
return function (y) {
return x + y
}
}
Focus on return
It might help to visualize it another way. We know that arrow functions work like this – let's pay particular attention to the return value.
const f = someParam => returnValue
So our add function returns a function – we can use parentheses for added clarity. The bolded text is the return value of our function add
const add = x => (y => x + y)
In other words add of some number returns a function
add(2) // returns (y => 2 + y)
Calling curried functions
So in order to use our curried function, we have to call it a bit differently …
add(2)(3) // returns 5
This is because the first (outer) function call returns a second (inner) function. Only after we call the second function do we actually get the result. This is more evident if we separate the calls on two lines …
const add2 = add(2) // returns function(y) { return 2 + y }
add2(3) // returns 5
Applying our new understanding to your code
related: ”What’s the difference between binding, partial application, and currying?”
OK, now that we understand how that works, let's look at your code
handleChange = field => e => {
e.preventDefault()
/// Do something here
}
We'll start by representing it without using arrow functions …
handleChange = function(field) {
return function(e) {
e.preventDefault()
// Do something here
// return ...
};
};
However, because arrow functions lexically bind this, it would actually look more like this …
handleChange = function(field) {
return function(e) {
e.preventDefault()
// Do something here
// return ...
}.bind(this)
}.bind(this)
Maybe now we can see what this is doing more clearly. The handleChange function is creating a function for a specified field. This is a handy React technique because you're required to setup your own listeners on each input in order to update your applications state. By using the handleChange function, we can eliminate all the duplicated code that would result in setting up change listeners for each field. Cool!
1 Here I did not have to lexically bind this because the original add function does not use any context, so it is not important to preserve it in this case.
Even more arrows
More than two arrow functions can be sequenced, if necessary -
const three = a => b => c =>
a + b + c
const four = a => b => c => d =>
a + b + c + d
three (1) (2) (3) // 6
four (1) (2) (3) (4) // 10
Curried functions are capable of surprising things. Below we see $ defined as a curried function with two parameters, yet at the call site, it appears as though we can supply any number of arguments. Currying is the abstraction of arity -
const $ = x => k =>
$ (k (x))
const add = x => y =>
x + y
const mult = x => y =>
x * y
$ (1) // 1
(add (2)) // + 2 = 3
(mult (6)) // * 6 = 18
(console.log) // 18
$ (7) // 7
(add (1)) // + 1 = 8
(mult (8)) // * 8 = 64
(mult (2)) // * 2 = 128
(mult (2)) // * 2 = 256
(console.log) // 256
Partial application
Partial application is a related concept. It allows us to partially apply functions, similar to currying, except the function does not have to be defined in curried form -
const partial = (f, ...a) => (...b) =>
f (...a, ...b)
const add3 = (x, y, z) =>
x + y + z
partial (add3) (1, 2, 3) // 6
partial (add3, 1) (2, 3) // 6
partial (add3, 1, 2) (3) // 6
partial (add3, 1, 2, 3) () // 6
partial (add3, 1, 1, 1, 1) (1, 1, 1, 1, 1) // 3
Here's a working demo of partial you can play with in your own browser -
const partial = (f, ...a) => (...b) =>
f (...a, ...b)
const preventDefault = (f, event) =>
( event .preventDefault ()
, f (event)
)
const logKeypress = event =>
console .log (event.which)
document
.querySelector ('input[name=foo]')
.addEventListener ('keydown', partial (preventDefault, logKeypress))
<input name="foo" placeholder="type here to see ascii codes" size="50">
Briefly
It is a function that returns another function written in a short way.
const handleChange = field => e => {
e.preventDefault()
// Do something here
}
// is equal to
function handleChange(field) {
return function(e) {
e.preventDefault()
// Do something here
}
}
Motivation
This technique can be utilized in a scenario where we have a callback function with fixed parameters, but we need to pass additional variables while avoiding global variables.
For instance, we have a button that has an onClick callback, and we want to pass a variable, such as id, but onClick accepts a single argument, event, making it impossible to pass id along with event.
const handleClick = (event, id) {
event.preventDefault()
// Dispatch some delete action by passing record `id`
}
It is not going to work.
Here as a solution, we write a function that returns another function with id in its variables scope without using any global variables:
const handleClick = id => event {
event.preventDefault()
// Dispatch some delete action by passing record `id`
}
const Confirm = props => (
<div>
<h1>Are you sure to delete?</h1>
<button onClick={handleClick(props.id)}>
Delete
</button>
</div
)
Function composition
Multiple arrow functions also are called "curried functions" and are used for function compositions.
import {compose} from 'redux'
import {store} from './store.js'
const pickSelectedUser = props => {
const {selectedName, users} = props
const foundUser = users.find(user => user.name === selectedName)
return foundUser.id
}
const deleteUser = userId => event => {
event.preventDefault()
store.dispatch({
type: `DELETE_USER`,
userId,
})
}
// The compose function creates a new function that accepts a parameter.
// The parameter will be passed throw the functions from down to top.
// Each function will change the value and pass it to the next function
// By changing value it was not meant a mutation
const handleClick = compose(
deleteUser,
pickSelectedUser,
)
const Confirm = props => (
<div>
<h1>Are you sure to delete?</h1>
<button onClick={handleClick(props)}>
Delete
</button>
</div
)
A general tip: If you get confused by any of new JavaScript syntax and how it will compile, you can check Babel. For example, copying your code in Babel and selecting the ES 2015 preset will give an output like this
handleChange = function handleChange(field) {
return function (e) {
e.preventDefault();
// Do something here
};
};
Understanding the available syntaxes of arrow functions will give you an understanding of what behaviour they are introducing when 'chained' like in the examples you provided.
When an arrow function is written without block braces, with or without multiple parameters, the expression that constitutes the function's body is implicitly returned. In your example, that expression is another arrow function.
No arrow funcs Implicitly return `e=>{…}` Explicitly return `e=>{…}`
---------------------------------------------------------------------------------
function (field) { | field => e => { | field => {
return function (e) { | | return e => {
e.preventDefault() | e.preventDefault() | e.preventDefault()
} | | }
} | } | }
Another advantage of writing anonymous functions using the arrow syntax is that they are bound lexically to the scope in which they are defined. From 'Arrow functions' on MDN:
An arrow function expression has a shorter syntax compared to function expressions and lexically binds the this value. Arrow functions are always anonymous.
This is particularly pertinent in your example considering that it is taken from a reactjs application. As as pointed out by #naomik, in React you often access a component's member functions using this. For example:
Unbound Explicitly bound Implicitly bound
------------------------------------------------------------------------------
function (field) { | function (field) { | field => e => {
return function (e) { | return function (e) { |
this.setState(...) | this.setState(...) | this.setState(...)
} | }.bind(this) |
} | }.bind(this) | }
Think of it like this, every time you see a arrow, you replace it with function.function parameters are defined before the arrow.
So in your example:
field => // function(field){}
e => { e.preventDefault(); } // function(e){e.preventDefault();}
and then together:
function (field) {
return function (e) {
e.preventDefault();
};
}
From the docs:
// Basic syntax:
(param1, param2, paramN) => { statements }
(param1, param2, paramN) => expression
// equivalent to: => { return expression; }
// Parentheses are optional when there's only one argument:
singleParam => { statements }
singleParam => expression
It might be not totally related, but since the question mentioned react uses case (and I keep bumping into this SO thread): There is one important aspect of the double arrow function which is not explicitly mentioned here.
Only the 'first' arrow(function) gets named (and thus 'distinguishable' by the run-time), any following arrows are anonymous and from React point of view count as a 'new' object on every render.
Thus double arrow function will cause any PureComponent to rerender all the time.
Example
You have a parent component with a change handler as:
handleChange = task => event => { ... operations which uses both task and event... };
and with a render like:
{
tasks.map(task => <MyTask handleChange={this.handleChange(task)}/>
}
handleChange then used on an input or click. And this all works and looks very nice. BUT it means that any change that will cause the parent to rerender (like a completely unrelated state change) will also re-render ALL of your MyTask as well even though they are PureComponents.
This can be alleviated many ways such as passing the 'outmost' arrow and the object you would feed it with or writing a custom shouldUpdate function or going back to basics such as writing named functions (and binding the this manually...)
The example in your question is that of a curried function which makes use of arrow function and has an implicit return for the first argument.
Arrow function lexically bind this i.e they do not have their own this argument but take the this value from the enclosing scope
An equivalent of the above code would be
const handleChange = (field) {
return function(e) {
e.preventDefault();
/// Do something here
}.bind(this);
}.bind(this);
One more thing to note about your example is that define handleChange as a const or a function. Probably you are using it as part of a class method and it uses a class fields syntax
so instead of binding the outer function directly, you would bind it in the class constructor
class Something{
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(field) {
return function(e) {
e.preventDefault();
// do something
}
}
}
Another thing to note in the example is the difference between implicit and explicit return.
const abc = (field) => field * 2;
Above is an example of implicit return ie. it takes the value field as argument and returns the result field*2 which explicitly specifying the function to return
For an explicit return you would explicitly tell the method to return the value
const abc = () => { return field*2; }
Another thing to note about arrow functions is that they do not have their own arguments but inherit that from the parents scope as well.
For example if you just define an arrow function like
const handleChange = () => {
console.log(arguments) // would give an error on running since arguments in undefined
}
As an alternative arrow functions provide the rest parameters that you can use
const handleChange = (...args) => {
console.log(args);
}
I have been reading a bunch of React code and I see stuff like this that I don't understand:
handleChange = field => e => {
e.preventDefault();
/// Do something here
}
That is a curried function
First, examine this function with two parameters …
const add = (x, y) => x + y
add(2, 3) //=> 5
Here it is again in curried form …
const add = x => y => x + y
Here is the same1 code without arrow functions …
const add = function (x) {
return function (y) {
return x + y
}
}
Focus on return
It might help to visualize it another way. We know that arrow functions work like this – let's pay particular attention to the return value.
const f = someParam => returnValue
So our add function returns a function – we can use parentheses for added clarity. The bolded text is the return value of our function add
const add = x => (y => x + y)
In other words add of some number returns a function
add(2) // returns (y => 2 + y)
Calling curried functions
So in order to use our curried function, we have to call it a bit differently …
add(2)(3) // returns 5
This is because the first (outer) function call returns a second (inner) function. Only after we call the second function do we actually get the result. This is more evident if we separate the calls on two lines …
const add2 = add(2) // returns function(y) { return 2 + y }
add2(3) // returns 5
Applying our new understanding to your code
related: ”What’s the difference between binding, partial application, and currying?”
OK, now that we understand how that works, let's look at your code
handleChange = field => e => {
e.preventDefault()
/// Do something here
}
We'll start by representing it without using arrow functions …
handleChange = function(field) {
return function(e) {
e.preventDefault()
// Do something here
// return ...
};
};
However, because arrow functions lexically bind this, it would actually look more like this …
handleChange = function(field) {
return function(e) {
e.preventDefault()
// Do something here
// return ...
}.bind(this)
}.bind(this)
Maybe now we can see what this is doing more clearly. The handleChange function is creating a function for a specified field. This is a handy React technique because you're required to setup your own listeners on each input in order to update your applications state. By using the handleChange function, we can eliminate all the duplicated code that would result in setting up change listeners for each field. Cool!
1 Here I did not have to lexically bind this because the original add function does not use any context, so it is not important to preserve it in this case.
Even more arrows
More than two arrow functions can be sequenced, if necessary -
const three = a => b => c =>
a + b + c
const four = a => b => c => d =>
a + b + c + d
three (1) (2) (3) // 6
four (1) (2) (3) (4) // 10
Curried functions are capable of surprising things. Below we see $ defined as a curried function with two parameters, yet at the call site, it appears as though we can supply any number of arguments. Currying is the abstraction of arity -
const $ = x => k =>
$ (k (x))
const add = x => y =>
x + y
const mult = x => y =>
x * y
$ (1) // 1
(add (2)) // + 2 = 3
(mult (6)) // * 6 = 18
(console.log) // 18
$ (7) // 7
(add (1)) // + 1 = 8
(mult (8)) // * 8 = 64
(mult (2)) // * 2 = 128
(mult (2)) // * 2 = 256
(console.log) // 256
Partial application
Partial application is a related concept. It allows us to partially apply functions, similar to currying, except the function does not have to be defined in curried form -
const partial = (f, ...a) => (...b) =>
f (...a, ...b)
const add3 = (x, y, z) =>
x + y + z
partial (add3) (1, 2, 3) // 6
partial (add3, 1) (2, 3) // 6
partial (add3, 1, 2) (3) // 6
partial (add3, 1, 2, 3) () // 6
partial (add3, 1, 1, 1, 1) (1, 1, 1, 1, 1) // 3
Here's a working demo of partial you can play with in your own browser -
const partial = (f, ...a) => (...b) =>
f (...a, ...b)
const preventDefault = (f, event) =>
( event .preventDefault ()
, f (event)
)
const logKeypress = event =>
console .log (event.which)
document
.querySelector ('input[name=foo]')
.addEventListener ('keydown', partial (preventDefault, logKeypress))
<input name="foo" placeholder="type here to see ascii codes" size="50">
Briefly
It is a function that returns another function written in a short way.
const handleChange = field => e => {
e.preventDefault()
// Do something here
}
// is equal to
function handleChange(field) {
return function(e) {
e.preventDefault()
// Do something here
}
}
Motivation
This technique can be utilized in a scenario where we have a callback function with fixed parameters, but we need to pass additional variables while avoiding global variables.
For instance, we have a button that has an onClick callback, and we want to pass a variable, such as id, but onClick accepts a single argument, event, making it impossible to pass id along with event.
const handleClick = (event, id) {
event.preventDefault()
// Dispatch some delete action by passing record `id`
}
It is not going to work.
Here as a solution, we write a function that returns another function with id in its variables scope without using any global variables:
const handleClick = id => event {
event.preventDefault()
// Dispatch some delete action by passing record `id`
}
const Confirm = props => (
<div>
<h1>Are you sure to delete?</h1>
<button onClick={handleClick(props.id)}>
Delete
</button>
</div
)
Function composition
Multiple arrow functions also are called "curried functions" and are used for function compositions.
import {compose} from 'redux'
import {store} from './store.js'
const pickSelectedUser = props => {
const {selectedName, users} = props
const foundUser = users.find(user => user.name === selectedName)
return foundUser.id
}
const deleteUser = userId => event => {
event.preventDefault()
store.dispatch({
type: `DELETE_USER`,
userId,
})
}
// The compose function creates a new function that accepts a parameter.
// The parameter will be passed throw the functions from down to top.
// Each function will change the value and pass it to the next function
// By changing value it was not meant a mutation
const handleClick = compose(
deleteUser,
pickSelectedUser,
)
const Confirm = props => (
<div>
<h1>Are you sure to delete?</h1>
<button onClick={handleClick(props)}>
Delete
</button>
</div
)
A general tip: If you get confused by any of new JavaScript syntax and how it will compile, you can check Babel. For example, copying your code in Babel and selecting the ES 2015 preset will give an output like this
handleChange = function handleChange(field) {
return function (e) {
e.preventDefault();
// Do something here
};
};
Understanding the available syntaxes of arrow functions will give you an understanding of what behaviour they are introducing when 'chained' like in the examples you provided.
When an arrow function is written without block braces, with or without multiple parameters, the expression that constitutes the function's body is implicitly returned. In your example, that expression is another arrow function.
No arrow funcs Implicitly return `e=>{…}` Explicitly return `e=>{…}`
---------------------------------------------------------------------------------
function (field) { | field => e => { | field => {
return function (e) { | | return e => {
e.preventDefault() | e.preventDefault() | e.preventDefault()
} | | }
} | } | }
Another advantage of writing anonymous functions using the arrow syntax is that they are bound lexically to the scope in which they are defined. From 'Arrow functions' on MDN:
An arrow function expression has a shorter syntax compared to function expressions and lexically binds the this value. Arrow functions are always anonymous.
This is particularly pertinent in your example considering that it is taken from a reactjs application. As as pointed out by #naomik, in React you often access a component's member functions using this. For example:
Unbound Explicitly bound Implicitly bound
------------------------------------------------------------------------------
function (field) { | function (field) { | field => e => {
return function (e) { | return function (e) { |
this.setState(...) | this.setState(...) | this.setState(...)
} | }.bind(this) |
} | }.bind(this) | }
Think of it like this, every time you see a arrow, you replace it with function.function parameters are defined before the arrow.
So in your example:
field => // function(field){}
e => { e.preventDefault(); } // function(e){e.preventDefault();}
and then together:
function (field) {
return function (e) {
e.preventDefault();
};
}
From the docs:
// Basic syntax:
(param1, param2, paramN) => { statements }
(param1, param2, paramN) => expression
// equivalent to: => { return expression; }
// Parentheses are optional when there's only one argument:
singleParam => { statements }
singleParam => expression
It might be not totally related, but since the question mentioned react uses case (and I keep bumping into this SO thread): There is one important aspect of the double arrow function which is not explicitly mentioned here.
Only the 'first' arrow(function) gets named (and thus 'distinguishable' by the run-time), any following arrows are anonymous and from React point of view count as a 'new' object on every render.
Thus double arrow function will cause any PureComponent to rerender all the time.
Example
You have a parent component with a change handler as:
handleChange = task => event => { ... operations which uses both task and event... };
and with a render like:
{
tasks.map(task => <MyTask handleChange={this.handleChange(task)}/>
}
handleChange then used on an input or click. And this all works and looks very nice. BUT it means that any change that will cause the parent to rerender (like a completely unrelated state change) will also re-render ALL of your MyTask as well even though they are PureComponents.
This can be alleviated many ways such as passing the 'outmost' arrow and the object you would feed it with or writing a custom shouldUpdate function or going back to basics such as writing named functions (and binding the this manually...)
The example in your question is that of a curried function which makes use of arrow function and has an implicit return for the first argument.
Arrow function lexically bind this i.e they do not have their own this argument but take the this value from the enclosing scope
An equivalent of the above code would be
const handleChange = (field) {
return function(e) {
e.preventDefault();
/// Do something here
}.bind(this);
}.bind(this);
One more thing to note about your example is that define handleChange as a const or a function. Probably you are using it as part of a class method and it uses a class fields syntax
so instead of binding the outer function directly, you would bind it in the class constructor
class Something{
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(field) {
return function(e) {
e.preventDefault();
// do something
}
}
}
Another thing to note in the example is the difference between implicit and explicit return.
const abc = (field) => field * 2;
Above is an example of implicit return ie. it takes the value field as argument and returns the result field*2 which explicitly specifying the function to return
For an explicit return you would explicitly tell the method to return the value
const abc = () => { return field*2; }
Another thing to note about arrow functions is that they do not have their own arguments but inherit that from the parents scope as well.
For example if you just define an arrow function like
const handleChange = () => {
console.log(arguments) // would give an error on running since arguments in undefined
}
As an alternative arrow functions provide the rest parameters that you can use
const handleChange = (...args) => {
console.log(args);
}
Rather than having the following 2 string functions and calling them both
removeTrailingSlash = (site) => site.replace(/\/$/, "");
getLastPartOfURL = (url) => url.substr(url.lastIndexOf('/') + 1);
I was hoping to be able to combine them into one high-order function definition
removeTrailingSlash = (site) => site.replace(/\/$/, "");
getLastPartOfURL = site => removeTrailingSlash => url => url.substr(url.lastIndexOf('/') + 1);
So I guess I am unclear how i can use arrow functions to do this or if there is a more elegant approach. Thanks.
A higher order function is a function that takes a function as an argument and/or returns a function.
This answer assumes you want to understand higher-order functions more (hence the title) and are not just looking for a better way to get the last part of a path (because this probably isn't it).
In your second example:
getLastPartOfURL = site => removeTrailingSlash => url => url.substr(url.lastIndexOf('/') + 1);
I read that getLastPartOfURL will be a function takes an argument site and returns a function that takes and argument removeTrailingSlash that returns a function that takes an argument url and then returns a substring of that url. Notice, that most of the arguments you passed in to these function (site, removeTrailingSlash) were not used.
For an arrangement like this, you can instead pass actual functions into those arguments and then compose the functions at the end for your final result.
For example:
//define a few simple functions
const removeTrailingSlash = (url) => url.replace(/\/$/, "");
const getLast = (url) => url.substr(url.lastIndexOf('/') +1 )
// define a higher order function that expects functions as arguments and composes them
const getLastPartOfURL = removeTrailingSlashFN => getLastFN => url => getLastFN(removeTrailingSlash(url))
// call it by passing in functions and url:
let result = getLastPartOfURL(removeTrailingSlash)(getLast)("http://www.example.com/test/")
console.log(result)
/* Notice that this arrangement allows you to make function partials! */
let partial = getLastPartOfURL(removeTrailingSlash)(getLast)
// now you only need to pass in url
console.log(partial("http://www.example.com/foo/"))
console.log(partial("http://www.example.com/bar/"))
There are a lot of other patterns, but hopefully this helps.
You already have a decent answer about higher-order functions, but I think the concept you might actually be looking for is function composition. Composition lets you define a new function that is the result of passing the result of one function into the input of another, like this:
const compose = (f, g) => x => f(g(x));
// Your original functions
const removeTrailingSlash = url => url.replace(/\/$/, "");
const getLast = url => url.substr(url.lastIndexOf('/') + 1);
const both = compose(getLast, removeTrailingSlash);
console.log(both('http://www.example.com/foo/'));
console.log(both('http://www.example.com/bar/'));
// You can even do another composition for logging
const logBoth = compose(console.log, both);
logBoth('http://www.example.com/foo/');
logBoth('http://www.example.com/bar/');
Note in this particular case, it is compose that is actually the higher order function. It takes two functions f and g as parameters and returns a new function as a result. The new combined function, both, isn't itself considered a higher-order function, even though it was created using one. It takes a string as a parameter and returns a string.
Also note that while you can define compose yourself as I did above, it is general purpose enough to be already included in libraries like Ramda.
I'm assuming that you're expecting to get an output of bar from an input of something like https://google.com/foo/bar/.
If that is the case then I recommend something like this.
url.split('/').filter(Boolean).pop();
This will split up your url into an array based on where the slashes are (in the example case it will be ['https:', '', 'google.com', 'foo', 'bar', '']), then it will filter out all of the empty strings, and then return the last item in the array (bar)
If you really want them to be different functions then I recommend something like Method chaining so you'll be able to do something like:
I am guessing you need a function that gets the last part of the url that ends with /.
const getLastPart = url => url.match(/\/(\w*)\/$/)[1];
const p = getLastPart('part1/part2/part3/');
console.log(p);
I suspect1 you just want getLastPartOfURL to call removeTrailingSlash before it returns:
const removeTrailingSlash = (url) => url.replace(/\/$/, '');
const getLastPartOfURL = (url) => {
const noTrailing = removeTrailingSlash(url); // call removeTrailingSlash
return noTrailing.substr(noTrailing.lastIndexOf('/') + 1);
};
const tests = [
'http://www.example.com',
'www.example.com/foo',
'http://www.example.com/foo/bar',
'http://www.example.com/foo/bar/',
'www.example.com/foo/index.html',
];
console.log(JSON.stringify(tests.map(getLastPartOfURL)));
1: A Higher-Order Function is a function that takes a function as a parameter, or returns a function as its output.