React observing

Advanced to do

Advanced to do

Here is an example of how to use react observing to build a advanced to do.

1import { IObservable, observe, selector, transform, useObserver, useObserverValue } from 'react-observing'
2
3// To do store
4const todosStore: IObservable<IObservable<string>[]> = observe([
5 observe(''),
6]);
7
8// Store the length of to dos based on "todosStore"
9const todosLengthStore = transform(todosStore, todos => todos.length);
10
11// Store the count of the length of all to dos based on "todosStore" and each to do
12const todosWordLengthStore = selector({
13 get: ({ get }) => {
14 const items = get(todosStore);
15
16 const length = items.reduce((count, todo) => {
17 return count += get(todo).length;
18 }, 0);
19
20 return length;
21 }
22});
23
24
25// This component will re-render only if a new to do is added
26const ItemsCount = () => {
27 const todosLength = useObserverValue(todosLengthStore);
28 return <p>(transform) Items count: {todosLength}</p>
29}
30
31// This component will re-render if a new to do is added and if any to do text if changed
32const WordCount = () => {
33 const todosWordLength = useObserverValue(todosWordLengthStore);
34 return <p>(selector) Words count in all items: {todosWordLength}</p>
35}
36
37// This component will be repeated for each to do, and will re-render only if your to do is changed
38const Input: React.FC<{ todoObservable: IObservable<string> }> = ({ todoObservable }) => {
39 const [todo, setTodo] = useObserver(todoObservable);
40 return <input value={todo} onChange={e => setTodo(e.target.value)} />
41}
42
43const TodoItem: React.FC<{ todoObservable: IObservable<string>, onRemove: () => void }> = ({ todoObservable, onRemove }) => {
44 return <li>
45 <ItemsCount />
46 <WordCount />
47 <button onClick={onRemove}>Remove</button>
48 <Input todoObservable={todoObservable} />
49 </li>
50}
51
52
53export const TodoList = () => {
54 const [todos, setTodos] = useObserver(todosStore);
55
56 return (
57 <div>
58 <h1>Todo list</h1>
59
60 <ItemsCount />
61 <WordCount />
62
63 <button onClick={() => setTodos(old => [...old, observe('')])}>Add item</button>
64
65 <ul>
66 {todos.map((todo, index) => (
67 <TodoItem
68 key={todo.id}
69 todoObservable={todo}
70 onRemove={() => setTodos(old => [...old.filter((_, i) => i !== index)])}
71 />
72 ))}
73 </ul>
74 </div>
75 )
76}
Edit this page on GitHub