-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexample.js
104 lines (85 loc) · 2.74 KB
/
example.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { render } from 'react-dom';
import { createElement as el, useCallback, useLayoutEffect, useRef, useState } from 'react';
import { createStore, getContext, observer, StoreProvider, useObservableStore } from './index.js';
let globalId = 0;
const useUpdateCounter = () => {
const countRef = useRef(0);
countRef.current++;
return countRef.current;
}
const store = createStore({
todos: {},
});
const addTodo = todo => state => {
state.todos[todo.id] = todo;
}
const deleteTodo = todoId => state => {
delete state.todos[todoId];
}
const toggleTodoDone = todoId => state => {
state.todos[todoId].done = true;
}
const setTodoDone = ({ todoId, done }) => state => {
state.todos[todoId].done = done;
console.log('when set', state.todos[todoId].done);
}
function UpdateCounter() {
const countRef = useRef(0);
countRef.current++;
return el('span', { className: 'updateCounter' }, countRef.current);
}
const Todo = observer(function Todo({ todo }) {
const [,dispatch] = useObservableStore();
const { id, text, done } = todo;
for (const key in todo) {
console.log(key);
}
console.log("id in todo", "id" in todo);
console.log("____ in todo", "____" in todo);
console.log(Object.getOwnPropertyDescriptor(todo, "id"));
console.log(Object.getOwnPropertyDescriptor(todo, "____"));
const onDeleteTodoClick = useCallback(event => {
dispatch(deleteTodo(id));
// Following would throw: "Observable `0.todos[todo.id].id` was accessed outside observer."
// dispatch(deleteTodo(todo.id));
}, [id])
const onTodoDoneChange = useCallback(event => {
dispatch(setTodoDone({
todoId: id,
done: event.target.checked,
}));
}, [id])
return el('li', {},
el('input', { type: 'checkbox', checked: done, onChange: onTodoDoneChange }),
el('span', {}, `${id} ${text}`, UpdateCounter()),
el('button', { type: 'button', onClick: onDeleteTodoClick }, 'Delete'),
)
})
const TodoList = observer(function TodoList() {
const [state] = useObservableStore();
return el('div', {},
el('h2', {}, `TodoList`, el(UpdateCounter)),
el('ul', {},
Object.values(state.todos).map(todo => el(Todo, { key: todo.id, todo })),
)
);
});
const TodoApp = observer(function TodoApp() {
const [,dispatch] = useObservableStore();
const onAddTodoClick = event => {
const text = window.prompt('Text');
if (text === null) return;
dispatch(addTodo({ id: globalId++, text, done: false }));
}
return el('div', {},
el('h1', {}, `TodoApp`, el(UpdateCounter)),
el(TodoList),
el('button', { type: 'button', onClick: onAddTodoClick }, 'Add new'),
)
});
render(
el(StoreProvider, { store },
el(TodoApp),
),
document.getElementById('root')
);