How to do it...

The component we want to create could have any kind of content. (The same idea would apply to generic dialog boxes, header sections, or sidebars, by the way.) Instead of creating a base class and using inheritance to create multiple derived classes, React allows you to pass a special children prop (this.props.children) so that you can pass children elements to the original component.

First, let's see how our ResultsDataTable code would change. First, the render() method would have to change:

render() {
if (this.props.results.length === 0) {
return <div className="bordered">No regions.</div>;
} else {
return (
<div className="bordered">
{this.props.results.map(x => (
<ExpandableCard key={x.id} title={x.name}>
<div>CITIES:{x.cities}</div>
<div>POPULATION:{x.pop}</div>
</ExpandableCard>
))}
</div>
);
}
}

Second, let's define the component we are using. We are inserting an ExpandableCard component with a key and a title, and within it we are including a couple of <div> elements with data for cities and population. This content will be available as this.prop.children, as we'll see later. We also added a title prop and an internal state, open, which will be toggled when you expand or condense a card via the .toggle() method. First, let's look at the props, state, and types:

// Source file: src/comopnents/expandableCard.2/index.js

/* @flow */

import * as React from "react";
import PropTypes from "prop-types";

import "../general.css";
import "./expandableCard.css";

export class ExpandableCard extends React.PureComponent<
{
children: React.ChildrenArray<React.ChildrenArray<React.Node>>,
title: string
},
{ open: boolean }
> {
static propTypes = {
children: PropTypes.arrayOf(PropTypes.element).isRequired,
title: PropTypes.string.isRequired
};

state = {
open: false
};

// continues...

For React, Flow predefines a lot of data types. (You can read more about this at https://github.com/facebook/flow/blob/master/website/en/docs/react/types.md.)

The few more usual ones you are likely to require are as follows, but read the aforementioned web page for a full list:

Data Types 
 Explanations 
React.ChildrenArray<T>
An array of children, of type <T>, just as shown in the previous code.
React.Element<typeof Component>
A node of a specific type: for example, React.Element<"div"> is an element that renders a <div>.
React.Key
The type of a prop that is used as key: essentially, either a number or a string.
React.Node
Any node that can be rendered, including React elements, numbers, strings, Booleans, undefined, null, or arrays of those types.

 

Finally, let's get to the functioning part of the component. Let's see how we show the children of the component when the state of the component shows that it should be expanded. Also of interest is looking at how clicking on the card calls the .toggle() method to change the component's state.open value:

// continued...

toggle = () => {
this.setState(state => ({ open: !state.open }));
}

render() {
if (this.state.open) {
return (
<div className="bordered">
{this.props.title}
<div
className="toggle"
onClick={this.toggle}
>

</div>
<div>{this.props.children}</div>
</div>
);
} else {
return (
<div className="bordered">
{this.props.title}
<div
className="toggle"
onClick={this.toggle}
>

</div>
</div>
);
}
}
}

We're done! Let's see how this all comes together.

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

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