Motivation
Learn some concepts of react while creating a todo list app
Let's start
A basic todo list would have following things for sure,
- add todo
- show todo
- delete todo
visualization is more important, they say..
so let’s create something like this…
Add TODO
To add an item we would need a simple textbox
<input type="text"/>
let's put some state in place
this.state = { new_text: "" }
now text box takes the value from our state
<input type="text" value={this.state.new_text} />
now if we type anything in the textbox, we may not see any values getting typed in the textbox,
because textbox is getting the value from the state and that is empty and not getting updated yet.
How do we update our state now ?
<input type="text" onChange={handleChange} value={todo.text} />
function,
handleChange(e) {
this.setState({ new_text: e.target.value })
}
now we have our todo in sync with component state,
but our state is handling one item at a time. we may have to update our state definition that stores multiple items,
this.state = {
items: [],
new_text: ""
}
let’s use form submit to set todo
<form onSubmit={this.handleSubmit}>
<input type="text" onChange={this.handleChange} value={this.state.new_text} />
<button>Add</button>
</form>
function,
handleSubmit(e){
e.preventDefault();
let newItem = {
new_text : this.state.new_text
}
this.setState(state=>({
items : state.items.concat(newItem),
new_text:''
}))
}
Note: when any form submit is performed, page re-renders hence preventing it,
event.preventDefault();
our next task is to show the todos in the list below the textbox.
Show todo
Add a list to show all the todos, to display the list items we add one more component [Todolist] and add a list in it
<ul>
{this.props.items.map(item=>(
<li>{item.new_text}
</li>
))}
</ul>
and display just below the textbox,
<Todolist items = {this.state.items} />
Now we have our app that lets us type text in text box , and shows the list under it, but what is this error in the console !!
this is caused when you are displaying items and has no unique identifier, hence we may have to add some unique identifier for the list item.
"Dates are important"
Let’s put the id wherever we are using our list items
handleSubmit(e){
e.preventDefault();
let newItem = {
new_text : this.state.new_text,
id: Date.now()
}
this.setState(state=>({
items : state.items.concat(newItem),
new_text:''
}))
}
and while showing the list items,
<ul>
{this.props.items.map(item=>(
<li key={item.id}>{item.new_text}
</li>
))}
</ul>
now we have our app running without any error.
This is the flow for our app,
Wait, we discussed delete as well right…
How do we accommodate delete functionality here, when one component triggers action and another component must be updated. Currently, child component does not have capability to update the state.
To achieve this, we will use react hooks.
There are many ways we can add hooks, I like the following,
we create a separate file that performs all the crud information on the state and uses the state internally
export const TodoRepo = (initialValue = []) => {
const [todos, setTodos] = useState([]);
return {
todos,
addTodo: item => {
if (item.new_text != "") {
setTodos(
todos.concat(item)
)
}
},
deleteTodo: item => {
if (item.new_text != "") {
setTodos(
todos.filter((td) => {
return td.id != item.id
})
)
}
}
}
};
and we use this js file in our first component [ Todo_App]
<ul>
{todos.map(item => (
<li key={item.id}>{item.new_text}<button onClick={()=>{deleteTodo(item)}}> delete</button></li>
))}
</ul>
Now we have the hooks configured in our app that adds/shows/deletes list items.I have setup the todo list with material-ui and have deployed here,
https://github.com/khatridev/react-todolist
I will keep adding more features in it, would be happy to hear any feedbacks.
Top comments (0)