Yet another tutorial on making Todo app in Reactjs — </>
Hello Good People, I have been trying to fiddle with ReactJs recently and was trying to work my way out to make a real simple Todo application. Which can
- Add to a list
- Delete from the list by simply clicking over it.
I will be trying to cover what is ReactJs to this “Todo” app as a conversation between two people, Kritika and Alpit (let's begin )
Kritika- Its weekend, I think we should make use of some new tech and try it out while we have time, like React? What say…!!!
Alpit- Sure, but whats React? :-O
Kritika- Well, for starters, its a library cooked up by the Facebook team, and is maintained by the community. The main advantage of using React is, it breaks up UI into small components, like a puzzle which can be later used to build up the big picture, and it's also very fast due to the virtual dom approach.
Alpit- Virtual dom? Is it a dom in memory?
Kritika- Yes, it's like a virtual blueprint of the real dom in the memory of React and every change is being happened in the virtual dom, and real dom is not touched unless the change is visually visible, as its expensive. You can understand this by, when you think, your thoughts are not conveyed to the listener until and unless you speak. You can mold your thought as many time you want, but once spoken it can't be taken back.
Alpit- Ooooooo..!!! philosophical, shall we get some hands-on now? What's the prerequisite?
Kritika- Just a couple of stuff
- A pc with Node installed (https://blog.teamtreehouse.com/install-node-js-npm-windows)
- A bit hands on with es6 JavaScript.
- A good editor (VScode preferred)
We will be using the create-react app, which will give us a good setup to start our coding directly. Run the following command in terminal, where you want to create the project.
npx create-react-app todo
This will take a couple of minutes. Sit and relax…!!!
When everything would be done, type
cd todo
npm start
You will see, your default browser opening and localhost:3000 already fired up, with an animated logo of react on the webpage. If that's the case then you are good to go.
This would be your default folder structure,
Now, open the App.js file in the src folder and clean all the mess inside file like this
import React, { Component } from 'react';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
</div>
);
}
}
export default App;
and delete everything from app.css
Alpit- My webpage is blank now, nice, but can you show me what the end result would look like?
Kritika- Certainly, it would help you to visualize how we are breaking the things up here.
As you can see, we are making two component, one having just a button and input box and second having the list. Now, just to keep a good practice and keep code manageable let us make two folders inside the src folder.
Name one as “inputBox” and other as “listTodo”,and make corresponding js and css files in it just like the image below.
Alpit- Uhhhh…!!!, that looks like a lot of folder and files, its just a simple application which can be written with just a simple JS, HTML and CSS, not with this much of complexity? Why go all this trouble?
Kritika- Hahaha…, certainly it is, a person coming from just a javaScript background would found it too much overwhelming. But as your application goes bigger, you will start appreciating the modular structure it provides and code reusability. You can just literally copy paste three lines of code, and voila the same feature is available in your next website.
Now, let's get back to code, and try to make the App.js file a bit useable. Let's add a constructor in the class and a state in it. Add the following lines in the class
constructor(props){
super(props)
this.state={
todo:[],
temp:''
}
}
Now, let's get this code line by line. Simply put, its just a constructor inside a class, where the super(props) call the constructor of super class in this case component. Now the main question what is the state over here?
What is the state in ReactJS ?
Its just an special object, can be modified over time in response to user actions, network responses, and anything. When it get modifes and change is visually available the dom is updated. (In a very layman term). It is available through out the whole file and can be access through a special method in other files too.
Your present code should be somewhat visible like this.
import React, { Component } from 'react';
import './App.css';
class App extends Component {constructor(props){
super(props)
this.state={
todo:[],
temp:''
}
}render() {
return (
<div className="App">
</div>
);
}
}
export default App;
Now, let's make our inputBox.js now 🙌 and just copy the below code and I will explain it line by line
import React from 'react';
import './inputBox.css'const inputBox = (props)=>{return(<div className="center">
<input className="inputDis" type="text" key='1' />
<button className="buttonDis" key='2'>Info</button></div>
)
}
export default inputBox
Now, one thing you must have noticed, between these two files. One contains a class and other a function, well its called state and stateless component respectively. You can use a class here as well, but since its small component without much of a fuss, prefer using a simple function call and return the JSX. Now, you got your inputField and a button.
Alpit- Ok, so far so good, but how it will know when we are adding and when we are typing?
Kritika- Good question, there are basically two handlers for it onChange() and onClick() lets quickly add these both to our code, I will be adding some extra stuff in the code and will be explaining it in a bit.
import React from 'react';
import './inputBox.css'const inputBox = (props)=>{return(<div className="center">
<input className="inputDis"
type="text"
onChange={props.changed}
key='1' /> <button className="buttonDis"
onClick={props.addTodo}
key='2'>Info</button></div>
)
}
export default inputBox
That extra bit which I said earlier is onChange={props.changed} and onClick={props.addTodo}
Alpit- Yes, I am all confused now..?? Howcome, suddenly props is referring to changed and addTodo and moreover what is even props ?🤷♂️
Kritika- Niceeeeeee…!!!, means you are following. See remember I told earlier about a technique related to state and how can we leverage it to use it in different other files. We are doing the same here, changed and addTodo will be functions defined in app.js and we are going to define it now. Add the following lines of code to your App.js class.
changed=(thing)=>{
var x = thing.target.value;
this.setState({
temp:x
})
}addTodo = ()=>{
const item = [
...this.state.todo
]
item.push(this.state.temp);
this.setState({
todo:item
})
}
Now, let me explain this code line by line.
You see there is an onChange method in the inputBox.js file inside its input element, this element fires off whenever there is a change in the input in textBox and it will call the changed() function of the App.js file.
Whenever it is called, the variable X is being overwritten and the temp value in the state is changed, by this.setState(). Now again go to your inputBox.js file. You will find one onClick method, this is self-explanatory, whenever it is clicked addTodo function is fired. All the todo list is being stored in an item array, by using the spread operator(google it😎 ), the new item is being pushed to it and again the state is set.
So by this, out one component inputBox(this is ready..!!!) and App.js(partially ready..!!!). Now let's make another component listTodo.
Alpit: Oh yes, there is one file remaining, but what is the use of this?
Kritika: Ok, basically, the use of this file is, its the list which is being displayed when the user adds some item. It's basically the second component. Just scroll up a bit to the image and you will find.
Alpit: Haha, that's cool, let's add code to it.
Kritka: Copy it down fast and it will be explained.
import React from 'react';
const displayTodo = (props)=>{const items = props.todoList.map((item, index)=>{
return(
<div key={index+"upper"}
onClick={()=>props.removeIt(index)}
className="listTodo">
<span>{item}</span>
</div>
)})
return (
<div>{items}</div>
);}
export default displayTodo
Alpit: Plsss stop..!!! and tell me how the data going into the prop?
Kritika: When we will combine all the component in App.js, you will get to know. Now the first google, how the map function works. It basically, iterate through the array and return something. In this case the same is happening, the data is being sent into {item} and then the whole list of div is being returned as {items}.
Now you must have seen there is an extra function named removeIt(). It will basically remove the todo item whenever it will be clicked.
Add these line just below addTodo
removeIt = (index)=>{
const newItems = this.state.todo.filter((el, elIndex) => elIndex!==index); this.setState({
todo: newItems
})
}
Simply put, in this function as the name suggest the filter method (inbuilt javaScript method) would filter out the element with an index not matching with the clicked index and putting it in the array and then set the state.
Alpit: Again I am asking? How are we invoking the method?
Kritika- Ok, now is the time, add these lines in your App.js in the render method.
render() {
return (
<div className="change">
<InputBox
changed={(event)=>this.changed(event)}
addTodo = {this.addTodo}
/>
<ListTodo
todoList = {this.state.todo}
removeIt = {this.removeIt}
/>
</div>
);
}
and voila..!!!, Your code is ready.
I am adding all the code over here as a final compiled version if you again have any doubt. This is App.js
//App.js
import React, { Component } from 'react';
import './App.css';
import Navbar from './Navbar/Navbar'
import InputBox from './inputBox/inputBox';
import ListTodo from './listTodo/listTodo';class App extends Component { constructor(props){
super(props)
console.log("This is from the construct");
this.state={
todo:[],
temp:''
}
} changed=(thing)=>{
var x = thing.target.value;
this.setState({
temp:x
})
} addTodo = ()=>{
const item = [
...this.state.todo
] item.push(this.state.temp);
this.setState({
todo:item
})
}
removeIt = (index)=>{
const newItems = this.state.todo.filter((el, elIndex) => elIndex !== index); this.setState({
todo: newItems
})}render() {
return (
<div className="change">
<InputBox
changed={(event)=>this.changed(event)}
addTodo = {this.addTodo}
/>
<ListTodo
todoList = {this.state.todo}
removeIt = {this.removeIt}
/>
</div>
);}}
export default App;
This is the listTodo.js
//listTodo.js
import React from 'react';
import {Button} from 'react-bootstrap';
import './listTodo.css'const displayTodo = (props)=>{
const items = props.todoList.map((item, index)=>{
return(
<div key={index+"upper"} onClick={()=>props.removeIt(index)} className="listTodo">
<span>{item}</span> </div>
)})
return (
<div>{items}</div>
);}
export default displayTodo
And the last file inputBox.js
//inputBox.jsimport React from 'react';
import './inputBox.css'
const inputBox = (props)=>{
return(<div className="center"><input className="inputDis" type="text" key='1' onChange={props.changed}/><Button className="buttonDis" key='2' onClick={props.addTodo}>Info</Button></div>
)}export default inputBox
Whoaahh..!!!, this was pretty long. However, this was my first attempt in writing any tutorial. This tutorial was written by keeping in mind you know React but you are just a beginner.
Any query regarding the code can be asked in comments, would love to answer them and if you want any further clarification here is my email alpitanand20@gmail.com. I have left the CSS part untouched, feel free to style as you like. Drop me a mail, regarding code or any opportunity for me.💖.
#alp