Part 4 — You’re here now.
The TodoList component
We’ve got a couple more things to do to make our failing e2e test pass; have a
.todo-text element and have it contain the text we submit in our form.
Create the folder structure
src/components/todoList/ and then write our first unit test in
test.js that will allow us to create our component:
This should be self explanatory, it’s very similar to how we started building our
What the component should return in the
Line 4 We’ll wrap our component in a
Then let’s test for a todo in the list:
Line 8 — 13 We create our
todos prop, an array containing one todo as an object with
Line 15 We actually pass that todo in as a prop to our component.
Line 22 We expect that our
todoList will contain a
.todo-text element with our todo text.
Now we just have to get our todo to render:
Line 2 import
PropTypes for our validation.
Line 18 — 25 We tell our component that it will receive a
todos, it will be an array of objects, its
id will be a number and
text will be a string, and everything is required. React prop-types validation.
Line 4 We pass the
todos prop in to our actual component.
Line 5 — 8 We
map over our array, returning an
li whose contents are the
todo.text and it has a
key is required by React to more efficiently know how to re-render the DOM and if you don’t have it you will get a console warning in dev.
Line 11 — 15 We return our
ul wrapper with all the
li's for each todo in our state.
At this point our
TodoList component knows how to render itself so can be wired in to our main App.
Line 5 import our
Line 18 — 23 Provide proper validation for it.
Line 8 Bring our todos array from state in to our App as a
prop so that we can pass it down. We’ve made it available as a
prop thanks to
Line 12 Add the
TodoList component to our
App and pass
todos from state to it.
We now get a test error because we’ve told the component it requires a
todos array but haven’t passed it in:
So we make that change:
Line 15 Simply pass an empty array to our
todos prop, that’ll stop our
App.test complaining. We don’t want to unit test child components at the parent level.
Now if we view our App in the browser we’ll find that we can actually display those lovely todos we’ve been storing in state. Huzzah!
And now our e2e test should pass:
Deleting a todo
First we write our e2e test:
Line 12 — 21 above to your e2e test.
This test runs through the same procedure as the one before and then clicks the
.todo-delete element and then expects the selector’s
state to equal ‘failure’. If it existed (was not deleted), it would equal ‘success’.
I like to implement functionality by writing the action, the reducer, creating the component, then adding it to the App.
So let’s test for the right action. First let’s create an appropriate constant:
Line 3 Our new DELETE_TODO constant.
Then, in the
action all we need to know to delete a todo will be its unique
Then add the code to make it pass:
And now let’s unit test our reducer functionality:
This should hopefully make a lot of sense by now. We’re giving our
startingState which includes a todo, passing it in the
action we just created which should delete that todo from the store, and expecting the returned state to indeed not contain the todo.
We now need to add another
case in our
reducer to handle this:
When the DELETE_TODO
action.type is encountered we return a new state which includes all of the existing
...state, and we override the
todos array to be only a filtered list where
todo.ids are not the same as the
action.id. Therefore all the
todos that are not the one we wanted to delete.
That was easy, wasn’t it?
Now let’s test our component can let us delete a todo:
Line 1 Add
jest to the eslint exceptions.
Line 8 Create a mock function for our delete functionality.
Line 10 — 18 Refactor our previous single
todos prop to be an object that holds all the props we need.
Line 20 Let our
component shallow render and unpack all the
props previously specified.
Line 30 — 34 Test that clicking on a
.todo-delete element does indeed call our
And then the code to make our test pass:
Line 36 Validation our
Line 4 Pass it in to our component.
Line 8 — 14 Add a ‘Delete’ button which will call the
deleteTodo function with the
todo.id as the argument on the
Now we need to hook it up to our UI via the App:
Line 36 — 38 Create the
deleteTodo prop that will dispatch the appropriate action.
Line 24 Validate it.
Line 8 Add it to the props for our component.
Line 12 Add it to the
And it’s really just that simple. Unit tests and e2e tests should be passing and the functionality should be working in our App in the browser.
Undelete a todo
If you’re still with me then you’re doing pretty good, and definitely not a newbie! So it’s time for a little challenge. I’m not going to tell you how to do this, why not give it a go yourself?
Think about what you need.
Just above you were able to TDD all the functionality to delete a todo, do the same for undelete. Also think about how, where and when you’re going to store your last deleted todo. With that in place it should click!
It won’t be too difficult to do this, it may take half an hour or a couple of hours but you can do it. Try and TDD it for a solid challenge.
Then check out how I did it:
So our App is sort of working, well the stuff we’ve tested is working. But if you try and use it you may discover some bugs that we’ve not coded for. You could branch off and try and fix them and add more functionality if you wish, but one final challenge I’ll pose you before you do that is to disable the ‘Add Todo’ and ‘Undelete’ buttons when it’s not appropriate to click them.
Have a think about how you could implement this, google around a bit and give it a shot. We both know you can do it!
When you’re done have a look at how I did it. I definitely wouldn’t say there was a right or a wrong way, just different approaches:
As a front ender it pains me to even call this styled but I guess this isn’t a CSS tutorial. If you want to make it pretty then fill your boots. This is just what mine happens to look like:
Deploying to Heroku
This is optional and just for a laugh, but if you do want to deploy your app online easily for free then Heroku offers a quick fix. This will allow you to play around with production builds and your own CI/CD pipelines if you so wish.
First Get set up with Heroku.
Then follow the instructions for the heroku-buildpack for React.
Visit the App online here.
Writing the readme
I’ve gone with the simple approach of just listing out how to setup, run and test our App.
Part 4 — You’re here now.
Aaand that’s it…
Yup, it really is. Have any feedback? Leave a message below.
I’m outie 9000.