Match Components and Data

Let’s put all of this new knowledge to use by creating something more concrete. We’ll build a word counter widget that takes some text and a target word count and displays the word count and a progress bar. In Chapter 2, Work with State and Events, we’ll learn how to update the text and the word count as the user types, but first, we’ll set up the word counter with a fixed text. When we’re done, our component will look like this:

images/wordcounter_new.png

In most applications, we don’t operate on a jumble of disconnected data; there are relationships between the data we work on. For example, the count and the progress bar are both based on the text. There are also relationships between UI elements, as user interface elements that display related data are often grouped together. We can take advantage of this fact to map the data to the user interface.

Let components mirror the relationships within the data. One component will perform the calculations, then use props to pass the results of the calculation to its children. Since components only receive data from their parents, it’s easier to trace where the data is coming from to debug the application.

This word counter is so simple, you could probably write it without any libraries, but it’s a great example because it will give you a feel for how to organize the component structure based on the data you need to display. To get started, let’s look at the relationships within the data. In this diagram, the arrows go from data to other data that derives from it:

images/data_relationships.png

The text and target word count are defined when you create the component. The count derives from the text, and the progress derives from the text and the target word count.

We could make one component that outputs the text box, the counter, and the progress bar, but it’s better to create these as separate components. In a larger application, small, focused components make it easier to understand what each component does, and it then becomes easier to refactor the application and move components around.

Spreading the application logic across many components makes it harder to follow, so we’ll try to keep it together. Instead of passing the text and the target to every component, we’ll calculate the count and progress in a container component higher up in the hierarchy. Then we’ll pass them as props to presentational components down the hierarchy.

Container components contain logic and perform calculations. Presentational components just display the props. Since props pass from parents to children, you must place smart components higher up in the hierarchy. Given these assumptions, let’s see how we can structure our components.

Starting with the markup alone avoids cognitive overload. It might look like this:

 <form class=​"editor"​>
  <textarea>User writes here</textarea>
  <div class=​"counter"​>Count goes here</div>
  <progress></progress>
 </form>

To extract our presentational components, we can create a component for each visible UI element: we’ll build one component for the <textarea>, one for the counter, and one for the progress. Let’s call them Counter, ProgressBar, and Editor. The container parent component will calculate the word count and the progress and pass them as props to its children. Let’s call it WordCounter. The final component structure will look like this:

 <WordCounter>
  <Editor/>
  <Counter/>
  <ProgressBar/>
 </WordCounter>

We’ve worked with container and presentational components and defined the component hierarchy for the word counter. Let’s dive into designing individual components.

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

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