Without Service
This is an alternate version withut teh use of a service. The service is replaced by a parent component that holds the mutations and passes it down to the child components.
See it in action
Todo List
Handle by the components only
- TodoListView.tsx (Parent)
- TodoListWithProps.tsx (Child)
import React from 'react';
import { TodoList } from './TodoListWithProps';
import { rippleHooks } from "./Lake";
// Extract the hook from the rippleHooks
const {useTasks} = rippleHooks;
export default function() {
const [tasks, setTask] = useTasks();
return <TodoList
addTask={(text: string) => {
tasks.todo.push({ id: Math.random().toString(36).substring(2, 9), text });
setTask();
}}
finishTask={(id: string) => {
const index = tasks.todo.findIndex((task) => task.id === id);
if (index !== -1) {
const task = tasks.todo.splice(index, 1)[0];
tasks.todo = tasks.todo.filter((task) => task.id !== id);
tasks.done.push(task);
}
setTask();
}}
removeTask={(id: string) => {
const index = tasks.done.findIndex((task) => task.id === id);
if (index !== -1) {
tasks.done = tasks.done.filter((task) => task.id !== id);
}
setTask();
}}
reset={() => {
setTask("reset");
}} />;
}
import React from 'react';
import { rippleHooks } from "./Lake";
// Extract the hook from the rippleHooks
const {useTasks} = rippleHooks;
// Defines the styles
const styles = {
mainContainer : {display: "flex", width: "320px", justifyContent: "space-between"},
lineContainer : {display: "flex", width: "320px", justifyContent: "space-between", marginTop: "5px"},
todoTask : {fontWeight: "bold", cursor: "pointer"},
doneTask : {textDecoration: " line-through", color: "grey", fontStyle: "italic"},
globalContainer : { border: "1px solid #ff79c6", padding: "15px", width: "350px"}
} as {[key: string]: React.CSSProperties};
type Props = {
addTask : (text: string) => void;
finishTask : (id: string) => void;
removeTask : (id: string) => void;
reset : () => void;
};
export function TodoList({addTask, finishTask, removeTask, reset}: Props) {
const [tasks] = useTasks();
const [todo, setTodo] = React.useState("");
return <>
<div style={styles.globalContainer}>
<div style={styles.mainContainer}>
<span>Todo List</span>
{/** Input box to add a nw task */}
<input type="text" value={todo} onChange={_ => setTodo(_.currentTarget.value)}/>
{/* Add the todo */}
<button
onClick={() => {
// If the todo is empty, we do not add it
if (!todo) return;
// Add the todo
addTask(todo);
// Reset the todo text
setTodo("");
}}>Add Todo</button>
</div>
{/** Reset the list */}
<button
onClick = {() => {reset();}}
style = {{marginTop: "5px", width: "100%"}}
>Reset the list</button>
{/** Display the list of todo tasks*/}
{tasks.todo.map((todo) => {
return (
<div style={styles.lineContainer}>
<div
key = {todo.id}
style = {styles.todotask}
>{todo.text}</div>
<button onClick={() => finishTask(todo.id)}>Done</button>
</div>
)
})}
{/** Display the list of done tasks*/}
{tasks.done.map((done) => {
return (
<div style={styles.lineContainer}>
<div
key = {done.id}
style = {styles.doneTask}
>{done.text}</div>
<button onClick={() => removeTask(done.id)}>Remove</button>
</div>
)
})}
</div>
</>
}
export default TodoList;