Pass Data To Event Handlers with Partial Function Application

Share this video with your friends

Send Tweet

In this lesson we’ll see how to pass an item’s id value in an event handler and get the state to reflect our change. We’ll also create a helper function that allows us to use partial function application to clean up the event handler code and make it more “functional”

Marko
Marko
~ 8 years ago

What is the reason using partially applied function instead of just binding arguments like it was?

Andy Van Slaars
Andy Van Slaars(instructor)
~ 8 years ago

Marko,

The point of pulling the binding out into a utility function is to make that reusable, cutting down on a bit of code in the JSX. This also opens up opportunities to partially apply arguments to any function, anywhere in your code. Say for instance you have a function that takes two arguments. You know the value of the first argument and you will get the second value as the result of a promise. You can create a partially applied version of that function with the known, first value, then in the then just pass a reference to that partially applied functions. When the promise resolves, that function will be invoked with both the initial argument and the result of the promise resolution.

Bottom line, there are a lot of places you can use partial application and when you use it a lot, it's easier to look at when you can avoid calls to bind(null, "value") all over the place.

Hope this helps.

Manuel Penaloza
Manuel Penaloza
~ 8 years ago

so to get it right... bind(null, "value") DOES NOT set this to null, but it leaves the context of the this keyword as it was when being defined in the parent component?

Andy Van Slaars
Andy Van Slaars(instructor)
~ 8 years ago

Correct:)

Gustavo Sequeira
Gustavo Sequeira
~ 8 years ago

Hi,

Using arrow function on React properties hurts performance, right? there is other way to do this? I'm looking at the onChange property of component.

Andy Van Slaars
Andy Van Slaars(instructor)
~ 8 years ago

Gustavo,

The end result of this is the use of the partial utility. That is defined as an arrow function, but could just as easily be a standard function statement or function expression. The way this is defined shouldn't have any performance implication since it is defined one time, outside of the component.

Hope this answers your question.

Gustavo Sequeira
Gustavo Sequeira
~ 8 years ago

Thanks for the quick response,

export const TodoItem = (props) => (
  <li>
    <input onChange={() => props.handleToggle(props.id)}
           type="checkbox"
           defaultChecked={props.isComplete}/>
    {props.name}
  </li>
);

So, Using () => props.handleToggle(props.id) on the onChange of TodoItem, doesn't mess with the performance? I had the idea that, using arrow functions or binding in JSX is not good for performance.

Andy Van Slaars
Andy Van Slaars(instructor)
~ 8 years ago

Gutavo,

You are correct, that code will impact performance. If you look at the end result of the lesson, you'll see that there is no arrow function in the onChange property:

https://github.com/avanslaars/egghead_react_todo_app_course/blob/lesson_13/src/components/todo/TodoItem.js#L5-L8

Gustavo Sequeira
Gustavo Sequeira
~ 8 years ago

Nice, congrats, awesome course.

Sebastián Alvarez
Sebastián Alvarez
~ 8 years ago

Andrew, first of all awesome course, I can say that I purchased PRO for this!.

Could you explain, maybe I am too newbie, why you bind to fn and dont directy call fn?

Thanks!

Andy Van Slaars
Andy Van Slaars(instructor)
~ 8 years ago

RaichuK,

Thanks, I'm so glad you enjoyed the course!

The onChange attribute needs a function as its value since that's what React will call when that event happens and we need that function to receive the item's id as an argument so we're using bind to partially apply the function with the id argument.

Our options are basically something like we started with where the onChange value is an arrow function that calls our method like onChange={() => props.handleToggle(props.id)} or we can use bind to get back the partially applied function. onChange={props.handleToggle.bind(null, props.id)}. Both of those options could get hard to read, which is why we created a partial utility function, so we have an abstraction that hides some of the ugly stuff away and we can keep the component code clean.

I hope this helps!

Oscar
Oscar
~ 7 years ago

Wow, so confused with this lesson. The Instructor goes through everything so fast :(

Michal Sedzielewski
Michal Sedzielewski
~ 7 years ago

I'm not sure that bind(null, value) doesn't override the context. A simple test proves that it happens:

const obj = { x: 1, xPlus: function(y) { return this.x + y}}
obj.xPlus(1) // -> 2
const xPlusOne = obj.xPlus.bind(null, 1)
xPlusOne() // -> NaN
Brackley Cassinga
Brackley Cassinga
~ 6 years ago

This lesson is kinda too abstract to me