React helper components

Production-ready applications need to be polished as much as possible. Implementing reusable React components is one of the most important things to do.

You should notice that drop-down menus are a common topic when building client-side applications. They are global parts of the front end and appear everywhere throughout our components.

It would be best to separate the actual menu markup that we want to display from the code, which handles the event-binding and showing the menu.

I always call this kind of code in React helper components. They are not implementing any business logic, but give us the opportunity to reuse drop-down menus or other features wherever we want.

Logically, the first step is to create a new folder to store all of the helper components, as follows:

mkdir src/client/components/helpers

Create a new file, called dropdown.js, as the helper component:

import React, { Component } from 'react';

export default class Dropdown extends Component {
state = {
show: false
}
handleClick = () => {
const { show } = this.state;
this.setState({show: !show});}
render() {
const { trigger, children } = this.props;
const { show } = this.state;

return(
<div className="dropdown">
<div>
<div className="trigger" onClick={this.handleClick}>
{trigger}
</div>
{ show &&
<div className="content">
{children}
</div>
}
</div>
</div>
)
}
}

We do not require much code to write a drop-down component. It is also pretty efficient, since this works with nearly every scenario that you can think of.

We use basic event-handling in the preceding code. When the trigger div tag is clicked, we update the show state variable. Inside of the div trigger, we also render a property called trigger. A trigger can be anything from a regular text or HTML tag to a React component. It can be passed through the parent components, in order to customize the look of the drop-down component.

In addition to the trigger property, we are using two well-known React patterns:

  • Conditional rendering, when the show variable is true
  • Rendering children given by the parent component

This solution allows us to fill in the menu items that we want to render directly as children of the Dropdown component, which, as mentioned previously, is displayed after clicking on the trigger. In this case, the show state variable is true.

However, one thing is still not completely correct here. If you test the drop-down component by providing a simple text or icon as a trigger and another text as the content, you should see that the Dropdown only closes when clicking on the trigger again; it does not close when clicking anywhere else in our browser, outside of the drop-down menu.

This is one scenario where the React approach encounters problems. There is no DOM Node event, like onClickOutside, so we cannot directly listen to the outside click events of any DOM Node, such as our drop-down menu. The conventional approach is to bind an event listener to the complete document. Clicking anywhere in our browser closes the drop-down menu.

There are many cases when it might make sense to leave the React approach and use the DOM directly, through the standard JavaScript interface. 

Read this article on Medium to get a better understanding: https://medium.com/@garrettmac/reactjs-how-to-safely-manipulate-the-dom-when-reactjs-cant-the-right-way-8a20928e8a6

Replace the handleClick method and add the componentWillUnmount React method, as follows:

componentWillUnmount() {
document.removeEventListener('click', this.handleClick, true);
}
handleClick = () => {
const { show } = this.state;

this.setState({show: !show}, () => {
if(!show) {
document.addEventListener('click', this.handleClick);
} else {
document.removeEventListener('click', this.handleClick);
}
});
}

When clicking on the trigger button, we add the click event listener to the whole document with the addEventListener function of JavaScript. This way, the handleClick function is re-executed when clicking anywhere.

When clicking on the drop-down trigger, or anywhere in the DOM, the event listener is removed again, by using the removeEventListener function.

Do not forget to remove all of the manually created event listeners whenever a component is unmounted and removed from the DOM. Forgetting this can lead to many errors, since the handleClick method will no longer be available from the event listener that it tries to call.

As mentioned previously, this is the part where React fails at least a little bit, although it is not the fault of React. The DOM and JavaScript do not have the right abilities.

We can finally use our helper component and display the context menus for posts, but first, we need to prepare all of the menu items and components that we want to render.

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

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