A ideia por trás deste tutorial é ensinar como utilizar o Context API para facilitar o desenvolvimento da sua aplicação react e evitar em alguns casos a utilização do redux, para gerenciamentos simples de estados globais.
Context
O context é o responsável por gerenciar os estados globais da nossa aplicação, nele ficará o estado a ser compartilhado pelos componentes e os métodos utilizados por eles, nesse caso temos apenas um estado a ser compartilhado, que é o todos e os métodos relacionados a ele são, inserção, atualização e exclusão.
No TodoProvider ficam armazenados o estado e métodos que devem ser compartilhados entre os componentes, ele recebe o parâmetro children, que são os componentes filhos que vão poder consumir tudo que foi declarado dentro dele.
import React, { useState, createContext } from "react";
export const TodoContext = createContext();
const TodoProvider = ({ children }) => {
const [todos, setTodos] = useState([
{ id: 1, title: "Estudar react", done: true },
{ id: 2, title: "Estudar webpack", done: false },
{ id: 3, title: "Estudar context", done: false },
{ id: 4, title: "Estudar redux", done: false },
]);
const saveTodo = (todo) => {
const newTodo = {
id: todo.length + 1,
title: todo.title,
done: false,
};
setTodos([...todos, newTodo]);
};
const removeTodo = (todoIndex) => {
todos.splice(todoIndex, 1);
setTodos([...todos]);
};
const checkTodo = (todoIndex) => {
const todo = todos[todoIndex];
todo.done = !todo.done;
setTodos([...todos]);
};
return (
<TodoContext.Provider value={{ todos, saveTodo, checkTodo, removeTodo }}>
{children}
</TodoContext.Provider>
);
};
export default TodoProvider;
Componente do formulário
O componente do formulário é responsável para criação de um novo todo, ele consome o método saveTodo do context.
import React, { useContext, useState } from "react";
import { TodoContext } from "../context/TodoContext";
const TodoForm = () => {
const { saveTodo } = useContext(TodoContext);
const [todo, setTodo] = useState();
const handleSubmit = (event) => {
event.preventDefault();
saveTodo(todo);
event.target.reset();
};
const handleInputChange = (event) => {
setTodo({
...todo,
title: event.target.value,
});
};
return (
<form onSubmit={handleSubmit} className="form-inline">
<div>
<input
type="text"
name="title"
className="form-control"
placeholder="Nova tarefa"
onChange={handleInputChange}
/>
<button type="submit" className="btn btn-default" />
</div>
</form>
);
};
export default TodoForm;
Componente da lista
O componente da lista será responsável por exibir os dados que estão salvos no estado e também por atualizar e excluir algum item da lista, para exibição ele utiliza o map que é um recurso do próprio javascript, já para a exclusão e atualização ele utiliza os métodos removeTodo e checkTodo eles são importados do context.
import React, { useContext } from "react";
import { TodoContext } from "../context/TodoContext";
function TodoList() {
const { todos, removeTodo, checkTodo } = useContext(TodoContext);
const handleDelete = (todoIndex) => {
removeTodo(todoIndex);
};
const handleDone = (todoIndex) => {
checkTodo(todoIndex);
};
return (
<ul>
{todos.map((todo, index) => (
<li className="list-group-item" key={index}>
<div className={todo.done ? "done" : "undone"}>
<span className="icon" onClick={() => handleDone(index)}></span>
<span>{todo.title}</span>
<button
type="button"
className="close"
onClick={() => handleDelete(index)}
>
×
</button>
</div>
</li>
))}
</ul>
);
}
export default TodoList;
Integração do context com os componentes
Por fim, é necessário fazer a integração dos componentes com o context, esse passo é o mais simples, importamos o nosso provider e colocamos os componentes que compartilham o mesmo estado dentro dele, depois disso todos esses componentes têm acesso ao estado e aos métodos que foram declarados no context.
import React from "react";
import TodoProvider from "./context/TodoContext";
import TodoForm from "./components/TodoForm";
import TodoList from "./components/TodoList";
import "./style.css";
const App = () => {
return (
<TodoProvider>
<div className="todoForm">
<h3 className="title">Lista de tarefas</h3>
<TodoForm />
<TodoList />
</div>
</TodoProvider>
);
};
export default App;
Obs: Em aplicações mais complexas onde se tem a necessidade de gerenciar muitos estados de diferentes maneiras, é mais recomendado se utilizar o redux ao invés de context api.
Repositório
Todo List 👩🏿💻
Top comments (0)