Adding elements to a div using React Hooks
I'm creating a todo list with React and found out that we use states in react unlike innerHTML
or appendChild()
in Javascript.
Here's where I'm facing the problem: When a user clicks a Button, a simple todo is added to the parent Div, and I mean 'Added not Replaced.
However, when using react hooks useState()
, It's just replacing the element, but I want to Add it to the div. Here's the code:
export default function TodoContainer() {
let [item, setItem] = useState('Nothing to show...');
function handleClick() {
setItem(item += <TodoItems/>)
}
return (
<div className="wholeContainer">
<div className="tododiv">
<span className="todos">Todos: </span>
<hr/>
{item}
</div>
<button className="add" onClick={handleClick}>
<i className="fas fa-plus"></i>
Add a Todo
</button>
</div>
);
}
So, when using setItem(item + <TodoItem/>)
, it just shows : [object Object]
Please help me, I don't know almost nothing about react as I just recently started learning it.
By the way, the <TodoItems/>
returns a div with a todo and its detail inside of it.
Thanks.
Yes, when you item += <TodoItems/>
you are appending a JSX literal to a (possibly) string, and the result seems to be interpreted as a Javascript object. Objects are not valid JSX and renderable.
You may want an array of todos for the state, and when adding a new todo add only the data, not the JSX. When adding a todo to the array you need to create a new array reference and shallow copy the previous state. You'll map the state to JSX in the render return.
Example:
export default function TodoContainer() {
const [todos, setTodos] = useState([]);
function handleClick() {
setTodos(todos => [...todos, "new todo"]);
}
return (
<div className="wholeContainer">
<div className="tododiv">
<span className="todos">Todos: </span>
<hr/>
{todos.length
? todos.map(todo => <TodoItems key={todo} todo={todo} />)
: 'Nothing to show...'
}
</div>
<button className="add" onClick={handleClick}>
<i className="fas fa-plus"></i>
Add a Todo
</button>
</div>
);
}