Skip to content

Instantly share code, notes, and snippets.

@andrzejewsky
Created March 31, 2019 00:01
Show Gist options
  • Save andrzejewsky/b213dbbcd7743814041f6a2b388830d0 to your computer and use it in GitHub Desktop.
Save andrzejewsky/b213dbbcd7743814041f6a2b388830d0 to your computer and use it in GitHub Desktop.
Todolist (with useContext and useReducer)
import React, { useState, useCallback, useContext, useReducer } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const TodoContext = React.createContext();
const reducer = (state, action) => {
switch (action.type) {
case "ADD_TODO":
return [...state, action.payload];
case "DELETE_TODO":
return state.filter(el => el.name !== action.payload);
case "CHECK_TODO":
return state.map(el => ({
...el,
checked: action.payload === el.name ? !el.checked : el.checked
}));
default:
return state;
}
};
const AddTodo = ({ onClickAdd }) => {
const dispatch = useContext(TodoContext);
const [todo, setTodo] = useState({ name: "", checked: false });
const handleChangeTodo = evt => {
setTodo({ name: evt.target.value, checked: false });
};
const handleAddClick = useCallback(() => {
if (todo) {
dispatch({ type: "ADD_TODO", payload: todo });
setTodo({ name: "", checked: false });
}
});
return (
<div className="add-form">
<input onChange={handleChangeTodo} value={todo.name} type="text" />
<button onClick={handleAddClick}>ADD</button>
</div>
);
};
const Item = ({ children, checked }) => {
const dispatch = useContext(TodoContext);
const handleCheck = useCallback(() =>
dispatch({ type: "CHECK_TODO", payload: children })
);
const handleDeleteClick = useCallback(() =>
dispatch({ type: "DELETE_TODO", payload: children })
);
return (
<li>
<input type="checkbox" onChange={handleCheck} checked={checked} />
<span>{children}</span>
<button onClick={handleDeleteClick}>delete</button>
</li>
);
};
const TodoList = () => {
const [todos, dispatch] = useReducer(reducer, []);
return (
<TodoContext.Provider value={dispatch}>
<div className="todo-list">
<div className="title">TodoList</div>
<AddTodo />
<ul>
{todos.map(todo => (
<Item key={todo.name} checked={todo.checked}>
{todo.name}
</Item>
))}
</ul>
</div>
</TodoContext.Provider>
);
};
function App() {
return (
<div className="App">
<h1>TodoList example</h1>
<TodoList />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment