React useState mental model
useState
- mental model of useState
- use array destructuring to get state and setState of the initial state value in a functional component
const [theme, setTheme] = React.useState("dark")
Mental model
- add state to functional components
- preserve values between function calls/renders and trigger a re-render of the component
-
React under the hood has some way to preserve values between function calls to prevent them from being garbage collected once the functon finishes executing
-
simple todo app with useState hook
import React, {useState} from "react";
import ReactDOM from "react-dom";
import "./styles.css";
/*
INSTRUCTIONS:
Create a "todo" app with the following criteria.
1. The user can add new todo items
2. The user can remove todo items
*/
function Todo () {
const [input, setInput] = useState("");
const [todos, setTodos] = useState([]);
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
const Item = ({ id, todo }) => (
<div style={{display: 'flex', alignItems:'center', justifyContent:'center'}}>
<h5 style={{marginRight: '5px'}}>{todo}</h5>
<button style={{borderRadius: '100%', height: '20px'}} onClick={() => removeTodo(id)}>X</button>
</div>
);
const onInputChange = (value) => setInput(value);
const addTodo = () => {
setTodos(todos => {
const createdTodo = { id: uuidv4(), todo: input};
return [...todos, createdTodo]
});
setInput("");
};
const removeTodo = (id) => {
const filteredTodos = todos.filter(todo => todo.id !== id)
setTodos(filteredTodos);
};
return (
<div>
<label>Todos</label><br/>
<input value={input} onChange={(event) => onInputChange(event.target.value)}/>
<button onClick={addTodo}>Add Todo</button>
<br/><br/>
<div>
{todos.map(({id, todo}) => (
<Item key={id} id={id} todo={todo}/>
))}
</div>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Todo />, rootElement);