A Committed Intro Guide to ReactJS, Part 3

Thomas Collardeau
7 min readApr 11, 2018

--

Welcome back to our app-building endeavor with ReactJS! In part 1, we bootstrapped a new app and acquainted ourselves with stateful components. In part 2, we delved right into React development. We used the lifecycle hook componentDidMount and we created an action to fetch data asynchronously and render a list of todos! Lastly, we refactored code to make use of stateless functional components.

There is a dedicated Github repo for this blog series. The commit history follows the steps taken in this guide. Feel free to fork the repo and checkout any commit to experiment along with this series!

Where we we?

We’re working right in the file src/App.js, which stands like this before we begin here in part 3. We have a little list of feature requirements, of which we already took care of the first two items.

Requirements:
X) display a loading text (while “fetching” todos) — done!
X) load and display todos
3) add new todos
4) toggle todos done/undone
5) delete todos

We’ve acquired much of the knowledge we need to tackle the last three features. Let’s begin with adding new todos

Adding New Todos

We need to accept input from the user creating new todos.

Creating a Form

Let’s build a Form component that will have a submit button, and a text input from which we will process new todo “titles”. Let’s sketch out such a form:

We’ve prepped the Form component, and the App (parent) component passes it all of its state and actions right there on line 38.

We could also pass down individual props (as Form is only using one prop thus far) for example:
<Form submit={this.actions.submit} />,
but this “prop drilling” gets tedious because you have to keep updating the parent component as you build the children components. For now, as we’re prototyping, I suggest we pass everything down by default; we can move faster and not to worry if the prop will be there in the child component. If prop drilling drives you mad, look into context, which was made official in React 16.3)

So, back to our little code review of our Form component. It has a onSubmit handler, which calls e.preventDefault to prevent an unwanted page reload from the browser, and then calls the submit action… that we still need to write, on line 16.

Controlled Input

Before we can submit the form however, we need to use that text input to get a todo title from the user. We’ll wire up a controlled input, meaning that we keep track of (and control) the value of our input from the state up top. Let me just show you what I mean:

Voila, we add a newTitle state (line 12) which is tied to the value of the form, on line 60. To change its value, we call our newly created action changeTitleInput on line 62 which does a setState on newTitle on line 17. Our controlled input is all wired up! The new title input is now on our state and we can access it from the root component!

Submitting the Form

All of a mere sudden, actions.submit has all that it needs because it can just look on this.state for the title input. Let’s tie up our implementation then:

Now users can submit todos

In the submit action, we call on our mock db to add a new todo to the database (which will callback our setState function from syncTodos, if you remember from part 2) so we’ll have that new todo just pop up on the screen. Hooray!

Also, we reset the input field on line 25 with:
this.setState({newTitle: '' })
so the input is empty again right after the user has submitted the form.

Finally, on line 70 we’re disabling the button when the input is empty, otherwise we’re making it possible to create empty todos which is not desirable. Here is what it looks like in the browser:

creating new todos

Destructuring Hipness

We’re done with “adding new post”, but let’s do one small (esthetic) enhancement; let’s destructure the props of our new Form component, so our code isn’t as repetitive:

Destructuring assignment syntax was recently added to JavaScript

We no longer have props all over the component and fewer “. chaining” in our JSX (props.submit becomes just submit). It’s also clearer what props we’re using in the rendering without scanning the entire component. The component is making use of newTitle, changeTitleInput, and submit as we can see at the top of the function. (Note that we can use this syntax because it’s been bundled for us via Babel and create-react-app from part 1 of this guide).

Sweetness! Let’s commit our changes. It may seem like a work of work but in the end we’ve only added 34 lines of code in this commit.

I’ve only destructured our new Form component above. Can you do the same for the Todos component?

Toggling Individual Todos

Let’s ride the wave… and tackle our next task: the toggling of individual todos as completed (done) or not. We’ll start by adding a controlled checkbox input for each mapped todo:

adding a controlled checkbox for each todo

We’re adding a checkbox input for each todo in our list. We’re “controlling” it via the todo’s done property, which is always initiated in the mockDB as false. Let’s create a new action to update the appropriate done key to its opposite (from false to true or vice-versa):

Are you ready to toggle?

The new action toggle on line 16 just needs the id of the todo, as it looks up its current done status on this.state, flips it with !, and updates the DB. The DB change triggers a new setState as part of our prior componentDidMount setup (see part 2 of this guide).

On line 55, we have to remember to do a little “drilling” with our actions: we pass all the actions down to the Todos component (because it’s now using the action toggle). Then we simply attach the toggle to the controlled checkbox via its onChange handler on line 88.

And we’re all done with the toggling!

A Touch of Style

It would be nice to have more visual feedback when a todo is done. Right now we only see the checkbox itself as an indication, which makes it a bit hard to tell if it’s even connected to the todos state at this point.

Let’s cross out an item when it is “done” by conditionally adding this CSS rule: text-decoration: line-through, so our UI end up like this:

Crossing out the text when the todo is marked done

We’ll take the opportunity to use CSS-IN-JSS, a technique popularized by React where you define CSS within the JS and basically abandon CSS files, (a bit similar to how we “handle HTML” in JS with React in fact). It looks like this in practice:

We can use the style property of an element and pass it an object (within a JS expression — that’s why the double bracket style={{ ... }}) . Each objet key is a CSS property, but you have to be careful to camel case it: the CSS text-decoration becomes textDecoration. Then we use the JS logical operator && to add the line-through when done is true. Now we have conditional styling.

Please note this implementation of CSS-IN-JS is rather naive and limiting. For example, you can’t use selectors like :hover. However, if you like this approach, I recommend you check out Styled Components.

Furthermore, check out the multitude of UI-Kits out there to style your React app. Perfect if you don’t have a designer onboard yet.

Deleting A Todo

Well, well… I leave this one up to you, partner! Why not send me a pull request on Github? Consider it a challenge. If you can complete the task, you’ll be well on your way to being a React dev!

Hint: you’ll be making use of db.deleteTodo which takes a todo id as a parameter. Good luck!

[update]: A PR has been merged. (Thanks Nick!)

The Bittersweet End

We’re arrived at the end of this guide. I hope you’ve enjoyed the content, and that you now feel comfortable with the key aspects of React development!

If we were to continue, what would you like to do next: add some tests? integrate a backend? add more features? Feel free to leave a comment. Feedback is always appreciated.

I’m also on Twitter.

Photo Credit
“A MacBook with lines of code displayed on its screen next to a mug” by Artem Sapegin

--

--