-
Notifications
You must be signed in to change notification settings - Fork 5
Open
Description
index.jsx
import React, { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./styles.css";
import App from "./App";
const root = createRoot(document.getElementById("root"));
root.render(<App />);TodoList.jsx
import { useSyncExternalStore } from "react";
function createTodoStore() {
let todos = [];
let listeners = new Set();
function notify() {
console.log({ listeners });
for (let listener of listeners) {
listener();
}
}
return {
subscribe(listener) {
listeners.add(listener);
return () => listeners.delete(listener);
},
getSnapshot() {
return todos;
},
addTodo(title) {
if (!title?.trim()) return;
todos = [
...todos,
{ id: crypto.randomUUID(), title: title.trim(), isCompleted: false },
];
notify();
},
toggleTodo(id) {
todos = todos.map((t) =>
t.id === id ? { ...t, isCompleted: !t.isCompleted } : t,
);
notify();
},
deleteTodo(id) {
todos = todos.filter((t) => t.id !== id);
notify();
},
};
}
const todoStore = createTodoStore();
// --- TodoList Component ---
export function TodoList() {
const todos = useSyncExternalStore(
todoStore.subscribe,
todoStore.getSnapshot,
);
console.log({ todos });
function handleAdd(e) {
e.preventDefault();
const formData = new FormData(e.currentTarget);
const title = formData.get("title")?.toString();
todoStore.addTodo(title);
e.currentTarget.reset();
}
return (
<>
<form onSubmit={handleAdd}>
<input name="title" placeholder="Enter a task" />
<button type="submit">Submit</button>
</form>
<ul>
{todos.map((todo) => (
<li key={todo.id}>
<input
type="checkbox"
checked={todo.isCompleted}
onChange={() => todoStore.toggleTodo(todo.id)}
/>
<span
style={{
textDecoration: todo.isCompleted ? "line-through" : "none",
}}
>
{todo.title}
</span>
<button onClick={() => todoStore.deleteTodo(todo.id)}>
Delete
</button>
</li>
))}
</ul>
</>
);
}