Getting component data

In this section, you'll learn about scenarios where the handler needs access to component properties, as well as argument values. You'll render a custom list component that has a click event handler for each item in the list. The component is passed an array of values as follows:

import React from 'react';
import { render } from 'react-dom';

import MyList from './MyList';

// The items to pass to "<MyList>" as a property.
const items = [
{ id: 0, name: 'First' },
{ id: 1, name: 'Second' },
{ id: 2, name: 'Third' }
];

// Renders "<MyList>" with an "items" property.
render(<MyList items={items} />, document.getElementById('root'));

 

Each item in the list has an id property, used to identify the item. You'll need to be able to access this ID when the item is clicked in the UI so that the event handler can work with the item. Here's what the MyList component implementation looks like:

import React, { Component } from 'react';

export default class MyList extends Component {
constructor() {
super();

// We want to make sure that the "onClick()"
// handler is explicitly bound to this component
// as it's context.
this.onClick = this.onClick.bind(this);
}

// When a list item is clicked, look up the name
// of the item based on the "id" argument. This is
// why we need access to the component through "this",
// for the properties.
onClick(id) {
const { name } = this.props.items.find(i => i.id === id);
console.log('clicked', `"${name}"`);
}

render() {
return (
<ul>
{/* Creates a new handler function with
the bound "id" argument. Notice that
the context is left as null, since that
has already been bound in the
constructor. */}
{this.props.items.map(({ id, name }) => (
<li key={id} onClick={this.onClick.bind(null, id)}>
{name}
</li>
))}
</ul>
);
}
}

Here is what the rendered list looks like:

You have to bind the event handler context, which is done in the constructor. If you look at the onClick() event handler, you can see that it needs access to the component so that it can look up the clicked item in this.props.items. Also, the onClick() handler is expecting an id parameter. If you take a look at the JSX content of this component, you can see that calling bind() supplies the argument value for each item in the list. This means that when the handler is called in response to a click event, the id of the item is already provided.

This approach to parameterized event handling is quite different from prior approaches. For example, I used to rely on getting parameter data from the DOM element itself. This works well when you only need one event handler, and it can extract the data it needs from the event argument. This approach also doesn't require setting up several new functions by iterating over a collection and calling bind().

And therein lies the trade-off. React applications avoid touching the DOM, because the DOM is really just a render target for React components. If you can write code that doesn't introduce explicit dependencies to DOM elements, your code will be portable. This is what you've accomplished with the event handler in this example.

If you're concerned about the performance implications of creating a new function for every item in a collection, don't be. You're not going to render thousands of items on the page at a time. Benchmark your code, and if it turns out that bind() calls on your React event handlers are the slowest part, then you probably have a really fast application.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.102.112