I have todos
array
of objects
passed as props
to a TodoList
component. I'm trying to add a new object
to the array
of objects
. I created a method called addTodo
which adds the first todo
's object
& when I tried to add the second todo it fails with the error: TypeError: this.state.todos.unshift is not a function
.
Two questions:
- Why it fails on the second try & works on the first try?
- how can I fix it?
This is my code:
import React, { Component } from 'react';
import './TodoListStyles.css'
class TodoList extends Component {
constructor(props){
super(props);
this.state = {
todos: this.props.todos,
value: ''
}
this.handleChange = this.handleChange.bind(this);
}
addTodo(e) {
e.preventDefault();
this.setState({
todos: this.state.todos.unshift({
id: this.state.todos.length + 1,
title: this.state.value,
completed: true
}),
value: ''
});
}
handleChange(e) {
this.setState({ value: e.target.value });
}
render() {
return (
<div>
<h1>Todos:</h1>
<form onSubmit={(e) => this.addTodo(e)}>
<input type='text' value={this.state.value} onChange={this.handleChange} />
</form>
<ul className='todo-list'>
{
this.props.todos.map(
todo =>
<React.Fragment key={todo.id}>
<li className={`todo-item ${todo.completed ? 'todo-item-completed' : ''}`}>{ todo.title }</li>
<input type='checkbox' checked={todo.completed} />
</React.Fragment>
)
}
</ul>
</div>
)
}
}
export default TodoList;
EDIT:
I refactored my code based on the explanation answer below to use concat()
method instead. I got rid of the error, but it doesn't add the object
to the array
. This is my new code:
addTodo(e) {
e.preventDefault();
const newItem = {
id: this.state.todos.length + 1,
title: this.state.value,
completed: true
};
this.setState((prevState) => {
prevState.todos.concat(newItem)
})
console.log(this.state.todos)
}```