Thinking in components - building a todo app

Thinking in components is about being able to break down an application in components. Consider something as simple as a Todo application. It will most likely consist of a number of components. Let's try and break that down.

A list of todos

We start off by a list of todos and we realise we need to be able to render said list. Before we consider how we should render it out on the screen, let's think about the underlying data structure.

A todo has a description. Next interesting thing to think about is how do we complete a todo. The intention of having a list of things we need to carry out it as at some point in time we will hopefully carry out those items on the list. Now we have to ask ourselves wether we want to remove a finished item in our todo list or simply mark it as completed. We opt for the latter to feel good about ourselves for completing it but also so what we can see what we have carried out historically. This tells us something about our data structure. It should most likely look something like this:

After that we need to figure out a way to change a todo in our list. We could be altering the todos list directly but the more React thing todo would be to create a todos state in the component, like so:

we go through the list, todo by todo until we find the selected todo then we change it state by doing an object spread:

return { ...t, done: !t.done }

Another thing worth noting is that our todo now consist of three properties:

title

done

id

We needed the id property to identify which todo we were trying to modify.

Create a todos component

So far we have everything inside of the App component and we don't want our entire application to live in there. What if we want to add other stuff. First thing we are going to do is to create a Todos component and thereby move the rendering, state and methods into that component. We will end up with the following files:

App.js - we had this from the beginning

Todos.js - this is new

Our Todos.js will contain pretty much all of what App.js used to contain:

Breaking down the todos component

So far Todos.js is one massive component. We can break it down according to responsibility. I mean it works to have it like it is but it's usually better to break down your app into small focused components, to make maintenance easier. Another reason is making it easier to use certain components in other places. So what can we break down Todos.js into? Well we can at least break it down into:

Todos, this would render a list of Todo components and handle all the events

Todo, this would only be responsible for rendering a Todo and send any change action upwards

Above we have broken out the Todo rendering into its own component. As you can see the component is not defined as a class inheriting from React.Component but is simply just a function. This is called a presentation or dumb component. What makes it dumb is that it knows nothing about the context it is in only that it relies on input, todo and invokes any action that it is being provided through its props, namely handleChecked(). Our Todos file now looks a bit simpler like so:

Above we simply let the Todo component handle all the rendering and we provide it with the data todo and the method handleChecked(). Ok so we mentioned presentational components so far so what is the other kind of component the container component. A container component is a component where data and logic lives. It 'contains' the meat of the application. In our app the Todos component is a container component and the Todo is a presentational component. If you are building your app in the right way you will end up with a majority of presentational components and a few container components.

Summary

We set out to create a working Todo app. We did so. We also set out to break down the mentioned app into many small components where each component was more focused on its task making future changes or reuse a lot easier. We introduced the term Dumb/Presentation component and Container component and explained what those were. to show that it only relied on inputs.