-
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor to utils module and middlewares
- Loading branch information
Showing
33 changed files
with
501 additions
and
316 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"words": [ | ||
"gettify", | ||
"immer", | ||
"immerify", | ||
"subscribify", | ||
"todomvc", | ||
"todos", | ||
"tsbuildinfo", | ||
"wouter", | ||
"zustand" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Overview | ||
|
||
An example of how to use `create-global-state` to build a scalable todo app. | ||
The example is intentionally split the app into tiny modules to show how to scale the app. | ||
So that when you update part of the state, only the minimal components will re-render, not the whole todo list or app. | ||
Compare the re-rendering with todomvc.com via [react chrome extension](https://chromewebstore.google.com/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en), you will see the difference: | ||
|
||
`create-global-state`: | ||
|
||
![create-global-state](https://github.com/user-attachments/assets/dc405ff6-fe6e-40f5-8703-e0a2e1aa7b8e) | ||
|
||
[todomvc.com](https://todomvc.com/examples/react/dist/): | ||
|
||
![todomvc](https://github.com/user-attachments/assets/9e175ab1-0a16-4819-a079-c3ffb4238695) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,46 @@ | ||
import { delTodo, toggleTodo, updateTodo, useTodo } from "./todos"; | ||
import { | ||
delTodo, | ||
toggleTodo, | ||
updateTodo, | ||
useTodo, | ||
useTodoDone, | ||
} from "./store/todos"; | ||
|
||
// The component to display a todo. | ||
export default function TodoItem({ id }: { id: number }) { | ||
const { done, text } = useTodo(id); | ||
type AttrID = { id: number }; | ||
|
||
// The component to display a todo. | ||
export default function TodoItem({ id }: AttrID) { | ||
return ( | ||
<div className="flex gap-1 my-1"> | ||
<input type="checkbox" checked={done} onChange={() => toggleTodo(id)} /> | ||
|
||
<input | ||
placeholder="Input text here" | ||
value={text} | ||
onChange={(e) => updateTodo(id, e.target.value)} | ||
disabled={done} | ||
autoFocus | ||
/> | ||
<Done id={id} /> | ||
<Input id={id} /> | ||
|
||
<button onClick={() => delTodo(id)} title="Delete current todo"> | ||
✕ | ||
</button> | ||
</div> | ||
); | ||
} | ||
|
||
function Done({ id }: AttrID) { | ||
return ( | ||
<input | ||
type="checkbox" | ||
checked={useTodoDone(id)} | ||
onChange={() => toggleTodo(id)} | ||
/> | ||
); | ||
} | ||
|
||
function Input({ id }: AttrID) { | ||
const { done, text } = useTodo(id); | ||
return ( | ||
<input | ||
placeholder="Input text here" | ||
value={text} | ||
onChange={(e) => updateTodo(id, e.target.value)} | ||
disabled={done} | ||
autoFocus | ||
/> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { setStore, useStore } from ".."; | ||
import { Filter } from "./types"; | ||
|
||
export const useFilter = () => { | ||
return useStore((state) => state.filter); | ||
}; | ||
|
||
export const setFilter = (filter: string) => { | ||
setStore((s) => { | ||
s.filter = filter as Filter; | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export const initFilter = "All"; | ||
|
||
export const filters = [initFilter, "Active", "Completed"] as const; | ||
|
||
export type Filter = (typeof filters)[number]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import create from "create-global-state"; | ||
import immer from "create-global-state/lib/immer"; | ||
import { Filter, initFilter } from "./filter/types"; | ||
import { initTodo } from "./todos/types"; | ||
import { compose } from "create-global-state/lib/utils"; | ||
import logger from "./logger"; | ||
|
||
export const initStore = { | ||
todos: [initTodo], | ||
filter: initFilter as Filter, | ||
}; | ||
|
||
export type Store = typeof initStore; | ||
|
||
const [useStore, baseSetStore] = create(initStore); | ||
|
||
const setStore = compose(baseSetStore, immer, logger); | ||
|
||
export { useStore, setStore }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { producer } from "create-global-state"; | ||
import { SetStoreX } from "create-global-state/lib/utils"; | ||
|
||
// Create a custom middleware to log all the state changes. | ||
export default function logger<S>(next: SetStoreX<S>): SetStoreX<S> { | ||
return (ns, opts) => { | ||
next((from) => { | ||
const to = producer(ns)(from); | ||
|
||
console.info("Change state", { from, to }); | ||
|
||
return to; | ||
}, opts); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { setStore, Store, useStore } from ".."; | ||
import { numbersEqual } from "./utils"; | ||
import { Filter } from "../filter/types"; | ||
import { useEqual } from "create-global-state/lib/utils"; | ||
|
||
// Get a todo by id. | ||
export function useTodo(id: number) { | ||
return useStore((s) => findTodo(s, id)); | ||
} | ||
|
||
export function useTodoDone(id: number) { | ||
return useStore((s) => findTodo(s, id).done); | ||
} | ||
|
||
// Get a new id list only when the ids of the todos change. | ||
export function useTodoIds() { | ||
return useStore( | ||
useEqual((s) => { | ||
return filterTodos(s, s.filter).map(({ id }) => id); | ||
}, numbersEqual) | ||
); | ||
} | ||
|
||
export function useZeroCount() { | ||
return useStore((s) => { | ||
return filterTodos(s, s.filter).map(({ id }) => id).length === 0; | ||
}); | ||
} | ||
|
||
// Get the count of the left todos. | ||
export function useLeftCount() { | ||
return useStore((s) => s.todos.filter(({ done }) => !done).length); | ||
} | ||
|
||
export function useZeroDone() { | ||
return useStore((s) => !s.todos.some(({ done }) => done)); | ||
} | ||
|
||
// Update the text of a todo by id. | ||
export function updateTodo(id: number, text: string) { | ||
setStore((s) => { | ||
findTodo(s, id).text = text; | ||
}); | ||
} | ||
|
||
// Toggle the done state of a todo by id. | ||
export function toggleTodo(id: number) { | ||
setStore((s) => { | ||
const todo = findTodo(s, id); | ||
if (todo) { | ||
todo.done = !todo.done; | ||
} | ||
}); | ||
} | ||
|
||
// Delete a todo by id. | ||
export function delTodo(id: number) { | ||
setStore((s) => { | ||
s.todos = s.todos.filter((todo) => todo.id !== id); | ||
}); | ||
} | ||
|
||
// Find a todo by id. | ||
function findTodo(s: Store, id: number) { | ||
return s.todos.find((todo) => todo.id === id)!; | ||
} | ||
|
||
// Filter the todos by the current status. | ||
export function filterTodos(s: Store, filter: Filter) { | ||
return s.todos.filter(({ done }) => { | ||
switch (filter) { | ||
case "All": | ||
return true; | ||
case "Active": | ||
return !done; | ||
case "Completed": | ||
return done; | ||
} | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export const initTodo = { | ||
id: Date.now(), | ||
text: "", | ||
done: false, | ||
}; | ||
|
||
export type Todos = (typeof initTodo)[]; |
File renamed without changes.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.