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);