Let's refactor the TaskCollection
component by introducing another component to represent a single task: TaskElement
. First, we will generate the scaffold for the TaskElement
component
kretes generate component TaskElement
This will gives us the following component at app/components/TaskElement.tsx
:
import React from 'react';
export const TaskElement: React.FC<{}> = () => {
return (
<div></div>
)
}
Before we provide the actual body of TaskElement
, let's use it right away as a building block in TaskCollection
.
import React from 'react';
import { TaskElement } from '@/components';
export const TaskCollection = ({ collection = [] }) => {
return (
<ul>
<TaskElement title="Learn Kretes" />
<TaskElement title="Build a web application" />
<TaskElement title="Show your app to the world" />
</ul>
);
}
We decided to pass the task title as the title
prop of TaskElement
to parametrize the title of each task. This decision requires us to adapt the newly created TaskElement
. We define the title as the component property (often referred to as prop). In the following example, our prop is title
and becomes the input parameter to the TaskElement
component function.
import React from 'react';
export const TaskElement: React.FC<{ title: string }> = ({ title }) => {
return (
<li>
<input type="checkbox" />
<label>{title}</label>
</li>
)
}
This is, however, not ideal. We repeat the component three times and the titles for tasks are written directly in the TaskCollection
component. Let's extract the data outside of that component and focus only on the relation between the collection and its elements.
We will assume that the data is passed into the TaskCollection
as the collection
prop. It's an array that represents the collection of our tasks. We can map over it to display as many TaskElement
s as needed.
import React from 'react';
import { TaskElement } from '@/components';
export const TaskCollection = ({ collection = [] }) => {
return (
<ul>
{collection.map(element => <TaskElement title={element.title} />)}
</ul>
);
}
As the field name in the collection matches the name of the prop in the TaskElement
, we can simplify the code a bit by destructuring each element directly into the props of the component:
import React from 'react';
import { TaskElement } from '@/components';
export const TaskCollection = ({ collection = [] }) => {
return (
<ul>
{collection.map(element => <TaskElement {...element} />)}
</ul>
);
}
Optionally, let's make the code in TaskCollection
more explicit to the compiler by annotating it using the Task
type we created previously.
import React from 'react';
import { TaskElement } from '@/components';
import { Task } from '@/types';
export const TaskCollection: React.FC<{ collection: Task[] }> = ({ collection = [] }) => {
return (
<ul>
{collection.map((element: Task) => <TaskElement {...element} />)}
</ul>
);
}
The final result is a 3-element, static list of tasks.
Found a mistake?Found a mistake? Would you like to suggest an improvement?