-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHooks.js
190 lines (176 loc) · 6.63 KB
/
Hooks.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
export default class Hooks {
static stateManager = null; // Shared state manager
static initialize(stateManagerInstance) {
Hooks.stateManager = stateManagerInstance;
}
static getOldHook() {
const oldHook =
Hooks.stateManager.getWipFiber().alternate &&
Hooks.stateManager.getWipFiber().alternate.hooks &&
Hooks.stateManager.getWipFiber().alternate.hooks[
Hooks.stateManager.getHookIndex()
];
return oldHook;
}
static useState(initial) {
const oldHook = Hooks.getOldHook();
const hook = {
state: oldHook ? oldHook.state : initial,
queue: [],
};
const actions = oldHook ? oldHook.queue : [];
actions.forEach((action) => {
hook.state = action(hook.state);
});
const setState = (action) => {
const isActionFunction = typeof action === "function";
hook.queue.push((currentState) => {
return isActionFunction ? action(currentState) : action;
});
let wipRoot = {
dom: Hooks.stateManager.getCurrentRoot().dom,
props: Hooks.stateManager.getCurrentRoot().props,
alternate: Hooks.stateManager.getCurrentRoot(),
};
// console.log("useState: wipRoot", wipRoot);
Hooks.stateManager.setWorkInProgressRoot(wipRoot);
Hooks.stateManager.setNextUnitOfWork(
Hooks.stateManager.getWorkInProgressRoot(),
);
Hooks.stateManager.setDeletions([]);
};
Hooks.stateManager.getWipFiber().hooks.push(hook);
Hooks.stateManager.setHookIndex(Hooks.stateManager.getHookIndex() + 1);
return [hook.state, setState];
}
static useEffect(effect, deps) {
const index = Hooks.stateManager.getHookIndex();
const wipFiber = Hooks.stateManager.getWipFiber();
const oldHook =
wipFiber.alternate &&
wipFiber.alternate.hooks &&
wipFiber.alternate.hooks[index];
if (oldHook) {
console.log("useEffect: oldHook", oldHook);
console.dir(oldHook);
const hasChangedDeps = deps
? !deps.every((dep, i) => dep === oldHook.deps[i])
: true;
console.log("useEffect: hasChangedDeps");
console.dir(hasChangedDeps);
if (hasChangedDeps) {
if (oldHook.cleanup) {
console.log("useEffect: cleanup", oldHook.cleanup);
oldHook.cleanup(); // Cleanup the previous effect
}
const cleanup = effect(); // Run the effect and store any cleanup function
wipFiber.hooks[index] = { deps, effect, cleanup }; // Update the hook with new values
console.log("useEffect: cleanup", cleanup);
} else {
console.log("Deps Not Changed : Skipping cleanup");
wipFiber.hooks[index] = oldHook; // Retain the old hook if dependencies haven't changed
}
} else {
console.log("First run of useEffect");
const cleanup = effect(); // This is the first run
wipFiber.hooks[index] = { deps, effect, cleanup }; // Create a new hook
}
Hooks.stateManager.setHookIndex(index + 1);
}
// static useEffect(effect, deps) {
// const oldHook =
// Hooks.stateManager.getWipFiber().alternate &&
// Hooks.stateManager.getWipFiber().alternate.hooks &&
// Hooks.stateManager.getWipFiber().alternate.hooks[
// Hooks.stateManager.getHookIndex()
// ];
// const hook = {
// deps,
// effect,
// cleanup: null,
// };
// if (oldHook) {
// console.log("useEffect: oldHook", oldHook);
// const hasChangedDeps = deps
// ? !deps.every((dep, i) => dep === oldHook.deps[i])
// : true;
// console.log("useEffect: hasChangedDeps");
// console.dir(hasChangedDeps);
// if (hasChangedDeps) {
// console.log("Deps Changed : Running cleanup");
// if (oldHook.cleanup) {
// console.log("useEffect: cleanup", oldHook.cleanup);
// oldHook.cleanup(); // Cleanup the previous effect
// }
// console.log("useEffect: effect" + effect);
// hook.cleanup = effect(); // Run the effect and store any cleanup function
// }
// else {
// console.log("Deps Not Changed : Skipping cleanup");
// hook.cleanup = oldHook.cleanup; // Reuse the cleanup function
// }
// } else {
// console.log("First run of useEffect");
// hook.cleanup = effect(); // This is the first run, so there are no old dependencies
// console.log("useEffect: hook.cleanup", hook.cleanup);
// console.dir(hook.cleanup);
// }
// console.log("useEffect: hook", hook);
// console.dir(hook);
// Hooks.stateManager.getWipFiber().hooks.push(hook);
// Hooks.stateManager.setHookIndex(Hooks.stateManager.getHookIndex() + 1);
// }
static useContext(context) {
const currentFiber = Hooks.stateManager.getWipFiber();
// console.log('Context: currentFiber', currentFiber);
const oldHook =
currentFiber.alternate &&
currentFiber.alternate.hooks &&
currentFiber.alternate.hooks[Hooks.stateManager.getHookIndex()];
// console.log('Context: oldHook', oldHook);
let hook;
if (oldHook) {
// console.log('Context: oldHook.state', oldHook.state);
// if (oldHook.cleanup) {
// oldHook.cleanup();
// }
hook = oldHook;
} else {
hook = {
state: context.value,
cleanup: null,
};
}
// Determine if this is a route context
const isRouteContext = context.isRouteContext || false;
if (context.subscribe && !hook.cleanup) {
// Only subscribe if we do not already have a cleanup function (to avoid duplicate subscriptions)
// console.log('Context: hook', hook);
hook.cleanup = context.subscribe(() => {
// console.log('Context value changed, updating hook state');
hook.state = context.value;
const wipRoot = {
dom: Hooks.stateManager.getCurrentRoot().dom,
props: Hooks.stateManager.getCurrentRoot().props,
alternate: Hooks.stateManager.getCurrentRoot(),
};
// console.log('Context: wipRoot', wipRoot);
Hooks.stateManager.setWorkInProgressRoot(wipRoot);
Hooks.stateManager.setNextUnitOfWork(
Hooks.stateManager.getWorkInProgressRoot(),
);
Hooks.stateManager.setDeletions([]);
});
if (isRouteContext) {
// For route contexts, modify how cleanup is handled
hook.cleanup = () => {
// Potentially log or handle the fact that routes do not cleanup in the usual way
// console.log("Route context cleanup called, no action taken.");
};
}
}
Hooks.stateManager.getWipFiber().hooks.push(hook);
Hooks.stateManager.setHookIndex(Hooks.stateManager.getHookIndex() + 1);
return hook.state;
}
}