Emitting and handling events

Communication between React components is of course not limited to components passing props to their children. Child components can also emit events for their ancestors to handle.

In the previous examples, we have already seen how to define callback functions to react to events.

Let's look again at the code of the Calculator component:

render() { 
    return ( 
       ... 
       <button onClick={() => this.add(1)}>+1</button> 
       ... 
    ); 
} 
 
add(value) { 
    this.setState((state, props) => { 
        return {currentResult: state.currentResult + value} 
    }); 
} 

In this example, the component associates the click event of the button child component to a local function. So, we already know how a parent can listen and react to events emitted by its children. Now, let's see how those children can emit custom events.

The solution is actually really simple: since a parent can pass props to its children, it can also pass a callback function as one of those props. In the React world, these are referred to as render props. They work like other props, but simply expect to receive a function and to return a React element; render props are therefore used for composition.

Here's an example with a parent component:

import React from 'react'; 
import {ChildComponent} from "./ChildComponent"; 
 
export class ParentComponent extends React.Component {  
    render() { 
        return ( 
            <ChildComponent onAdd={this.add}/> 
        ); 
    } 
 
    add(value) { console.log(`Parent has received the following value: 
${value}`); } }

And the following is its child:

import React from 'react'; 
 
export class ChildComponent extends React.Component {  
    render() { 
        return ( 
            <button onClick={() => this.props.onAdd(1)}>+1</button> 
        ); 
    } 
} 

In this simple example, ParentComponent defines an add method that it passes down to ChildComponent through an onAdd prop. As you can see, ChildComponent receives it and simply calls it when the button is clicked upon.

You can find the source of the preceding example in the code samples of this book, under Chapter11/07-render-props.

There are traps that you could easily fall into regarding the usage of the this keyword within this kind of callback function. You can learn about these here: https://reactjs.org/docs/handling-events.html. Actually, we have already learned how to avoid such issues using TypeScript.

If you want to fix the issue, then you need to change this:

add(value) { 
    console.log(`Parent has received the following value: ${value}`); 
} 

The following is what it should be changed into:

add = (value) => { 
    console.log(`Parent has received the following value: ${value}`); 
} 

With this change applied, calling this.add will work as expected. With the first form, this would, in fact, be pointing to the props object passed to ChildComponent when invoked in the click event handler of ChildComponent!

Render props are simple props, but they serve a particular purpose. They are useful since they allow us to reuse logic across components. As an added benefit, as we've just seen, they also enable simple communication between components.

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

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