Skip to content

Instantly share code, notes, and snippets.

View Georgegriff's full-sized avatar

George Griffiths Georgegriff

View GitHub Profile
@Georgegriff
Georgegriff / TodoProvider.jsx
Last active January 10, 2022 10:46
hooks mutations - mutations removed
removeTodo: (id) => {
// make a copy first
const newTodos = new Map(draftTodos);
if (newTodos.delete(id)) {
setTodoList(newTodos);
}
},
addTodo: (message) => {
if (!message) {
return;
@Georgegriff
Georgegriff / TodoProvider.jsx
Created January 10, 2022 10:43
hooks mutations - saving
// And inside of the save function, removed existingTodos() as its not a function anymore
{
save: () => {
const existingTodoKeys = Array.from(existingTodos.keys());
/// ...
const existingTodoValues = Array.from(existingTodos.values());
};
}
@Georgegriff
Georgegriff / TodoProvider.jsx
Created January 10, 2022 10:43
hooks mutations - switch to useMemo
// main change - change to use useMemo which means existingTodos is the todos, not a function.
const existingTodos = useMemo(() => {
const todoMap = new Map();
apiResponse?.todos.forEach((todo) => {
todoMap.set(todo.id, todo);
});
return todoMap;
}, [apiResponse]);
@Georgegriff
Georgegriff / TodoProvider.jsx
Created January 10, 2022 10:41
hooks mutations - saving
<TodoContext.Provider
value={{
save: () => {
// contrived code for the demonstration
// in the real app this was responsible for deciding if a request should be sent to server or not
const existingTodoKeys = Array.from(existingTodos().keys());
const draftTodoKeys = Array.from(draftTodos.keys());
let todosHasChanges = existingTodoKeys.length !== draftTodoKeys.length;
// now check entries using ids, unless we know they have changed based on length
// there are better ways of detecting changes but this demonstrates the issue
@Georgegriff
Georgegriff / TodoProvider.jsx
Created January 10, 2022 10:40
hooks mutations - TodoProvider adding and removing items
<TodoContext.Provider
value={{
todoItems: draftTodos ? Array.from(draftTodos.values()) : [],
removeTodo: (id) => {
if (draftTodos.delete(id)) {
setTodoList(new Map(draftTodos));
}
},
addTodo: (message) => {
if (!message) {
@Georgegriff
Georgegriff / TodoProvider.jsx
Created January 10, 2022 10:39
hooks mutations - todoProvider with initial set of drafts
export const TodoProvider = ({ children }) => {
// New line here!
const [draftTodos, setTodoList] = useState();
const [apiResponse, setApiResponse] = useState(undefined);
useEffect(() => {
const fetchTodos = async () => {
const res = await fetch("./todos.json");
const response = await res.json();
setApiResponse(response);
@Georgegriff
Georgegriff / transformed-todos.json
Created January 10, 2022 10:38
hooks mutations article - id map
{
1: {
"id": 1,
"message": "Go to the supermarket",
"done": false
},
2: {
"id": 2,
"message": "Mow the lawn",
"done": true
@Georgegriff
Georgegriff / TodoProvider.jsx
Last active January 10, 2022 10:35
hooks mutations article - TodoProvider
export const TodoContext = createContext();
export const TodoProvider = ({ children }) => {
const [apiResponse, setApiResponse] = useState(undefined);
const [draftTodos, setTodoList] = useState();
useEffect(() => {
const fetchTodos = async () => {
const res = await fetch("./todos.json");
const response = await res.json();
@Georgegriff
Georgegriff / todos.json
Created January 10, 2022 10:34
react mutations blog post - todos
{
"todos": [
{
"id": 1,
"message": "Go to the supermarket",
"done": false
},
{
"id": 2,
"message": "Mow the lawn",
@Georgegriff
Georgegriff / AddTodo.jsx
Created January 10, 2022 10:33
hooks mutations article snippet - AddTodo
import { useTodos } from "./TodoContext";
export const AddTodo = () => {
const { addTodo } = useTodos();
return (
<form
onSubmit={(e) => {
e.preventDefault();
const formEntries = new FormData(e.target);