Skip to content

Commit 422f334

Browse files
prevented useEffect from crashing on load
1 parent 3b1f86c commit 422f334

File tree

2 files changed

+34
-64
lines changed

2 files changed

+34
-64
lines changed

package/linkFiber.js

Lines changed: 33 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,32 @@
11
/* eslint-disable func-names */
22
/* eslint-disable no-use-before-define */
33
/* eslint-disable no-param-reassign */
4-
54
// links component state tree to library
65
// changes the setState method to also update our snapshot
7-
86
const Tree = require('./tree');
97
const astParser = require('./astParser');
10-
const { saveState } = require('./masterState'); // saves AST state as array for later use
8+
const { saveState } = require('./masterState');
119

1210
module.exports = (snap, mode) => {
13-
// snap is the current tree
14-
// mode is {jumping: bool, locked: bool, paused: bool
15-
1611
let fiberRoot = null;
1712
let astHooks;
1813

19-
function sendSnapshot() { // send snapshot of current fiber tree to chrome extension ?
14+
function sendSnapshot() {
2015
// don't send messages while jumping or while paused
21-
// DEV: So that when we are jumping to an old snapshot it wouldn't think we want to create new snapshots
16+
// DEV: So that when we are jumping to an old snapshot it
17+
// wouldn't think we want to create new snapshots
2218
if (mode.jumping || mode.paused) return;
23-
const payload = snap.tree.getCopy(); // copy of current react fiber tree
19+
const payload = snap.tree.getCopy();
2420
// console.log('payload', payload);
25-
window.postMessage({ // send to window
21+
window.postMessage({
2622
action: 'recordSnap',
2723
payload,
2824
});
2925
}
3026

31-
function changeSetState(component) { // if invoked, change setState functionality so that it also updates our snapshot
32-
// console.log("what is component?", component);
27+
function changeSetState(component) {
3328
// check that setState hasn't been changed yet
34-
if (component.setState.linkFiberChanged) {
35-
// console.log("setState has already been changed for", component);
36-
return;
37-
}
29+
if (component.setState.linkFiberChanged) return;
3830
// make a copy of setState
3931
const oldSetState = component.setState.bind(component);
4032
// replace component's setState so developer doesn't change syntax
@@ -43,34 +35,29 @@ module.exports = (snap, mode) => {
4335
// don't do anything if state is locked
4436
// UNLESS we are currently jumping through time
4537
if (mode.locked && !mode.jumping) return;
46-
// continue normal setState functionality, except add sending message (to chrome extension) middleware
38+
// continue normal setState functionality, except add sending message middleware
4739
oldSetState(state, () => {
48-
updateSnapShotTree(); // this doubles the actions in reactime for star wars app, also invokes changeSetState twice, also invokes changeSetState with Route and Characters
49-
sendSnapshot(); // runs once on page load, after event listener: message (line 145)
50-
callback.bind(component)(); // WHY DO WE NEED THIS ?
40+
updateSnapShotTree();
41+
sendSnapshot();
42+
callback.bind(component)();
5143
});
5244
};
53-
component.setState.linkFiberChanged = true; // we changed setState.
45+
component.setState.linkFiberChanged = true;
5446
}
5547

56-
function changeUseState(component) { // if invoked, change useState dispatch functionality so that it also updates our snapshot
57-
// check that changeUseState hasn't been changed yet
48+
function changeUseState(component) {
5849
if (component.queue.dispatch.linkFiberChanged) return;
5950
// store the original dispatch function definition
60-
61-
// not sure why we need the bind, seems to work without it
62-
// const oldDispatch = component.queue.dispatch.bind(component.queue);
63-
const oldDispatch = component.queue.dispatch;
64-
51+
const oldDispatch = component.queue.dispatch.bind(component.queue);
6552
// redefine the dispatch function so we can inject our code
6653
component.queue.dispatch = (fiber, queue, action) => {
67-
// don't do anything if state is locked, UNLESS we are currently jumping through time
54+
// don't do anything if state is locked
6855
if (mode.locked && !mode.jumping) return;
69-
oldDispatch(fiber, queue, action); // hooks sees this and thinks its a side effect, that's why it's throwing an error
70-
// setTimeout(() => {
71-
updateSnapShotTree();
72-
sendSnapshot();
73-
// }, 100);
56+
oldDispatch(fiber, queue, action);
57+
setTimeout(() => {
58+
updateSnapShotTree();
59+
sendSnapshot();
60+
}, 100);
7461
};
7562
component.queue.dispatch.linkFiberChanged = true;
7663
}
@@ -83,13 +70,8 @@ module.exports = (snap, mode) => {
8370
let index = 0;
8471
astHooks = Object.values(astHooks);
8572
// while memoizedState is truthy, save the value to the object
86-
while (memoizedState && memoizedState.queue !== null) {
87-
// we only want to changeUseState (which updates and sends the snapshot)
88-
// on the last item in the memoizedState chain. This makes sure it doesn't double-push
89-
// values to the timeline.
90-
if (astHooks[index + 2] === undefined) {
91-
changeUseState(memoizedState);
92-
}
73+
while (memoizedState && memoizedState.queue) { // prevents useEffect from crashing on load
74+
changeUseState(memoizedState);
9375
// memoized[astHooks[index]] = memoizedState.memoizedState;
9476
memoized[astHooks[index]] = memoizedState.memoizedState;
9577
// Reassign memoizedState to its next value
@@ -101,72 +83,60 @@ module.exports = (snap, mode) => {
10183
}
10284

10385
function createTree(currentFiber, tree = new Tree('root')) {
104-
// if there is no current fiber just return the new tree as-is
10586
if (!currentFiber) return tree;
106-
// console.log("what is currentFiber", currentFiber);
87+
10788
const {
10889
sibling,
10990
stateNode,
11091
child,
11192
memoizedState,
11293
elementType,
113-
} = currentFiber; // extract properties of current fiber
94+
} = currentFiber;
11495

115-
let childTree = tree; // initialize child fiber tree as current fiber tree
96+
let nextTree = tree;
11697
// check if stateful component
11798
if (stateNode && stateNode.state) {
11899
// add component to tree
119-
childTree = tree.appendChild(stateNode); // returns newly appended tree
100+
nextTree = tree.appendChild(stateNode);
120101
// change setState functionality
121102
changeSetState(stateNode);
122103
}
123104
// Check if the component uses hooks
124-
125105
if (memoizedState && Object.hasOwnProperty.call(memoizedState, 'baseState')) {
126106
// Traverse through the currentFiber and extract the getters/setters
127107
astHooks = astParser(elementType);
128108
saveState(astHooks);
129109
// Create a traversed property and assign to the evaluated result of
130110
// invoking traverseHooks with memoizedState
131111
memoizedState.traversed = traverseHooks(memoizedState);
132-
childTree = tree.appendChild(memoizedState);
112+
nextTree = tree.appendChild(memoizedState);
133113
}
134114
// iterate through siblings
135115
createTree(sibling, tree);
136116
// iterate through children
137-
createTree(child, childTree);
117+
createTree(child, nextTree);
138118

139119
return tree;
140120
}
141-
142-
// runs when page initially loads and on subsequent state changes
121+
// runs when page initially loads
143122
// but skips 1st hook click
144123
function updateSnapShotTree() {
145-
const { current } = fiberRoot; // on initial page load, current - fiberNode is tag type HostRoot (entire fiber tree)
146-
console.log('current', current);
124+
const { current } = fiberRoot;
147125
snap.tree = createTree(current);
148126
}
149127

150-
// RUNS ONCE, ON INITIAL PAGE LOAD ?
151128
return container => {
152-
// on first page load, container is entire html hierarchy of top level div
153-
// _reactRootContainer is that invisible top level object which wraps the top level div
154-
// _reactRootContainer._internalRoot is an object with property .current which includes HostRoot fiberNode (entire fiber tree)
155129
const {
156130
_reactRootContainer: { _internalRoot },
157131
_reactRootContainer,
158132
} = container;
159-
// only assign internal root if it actually exists
133+
// only assign internal rootp if it actually exists
160134
fiberRoot = _internalRoot || _reactRootContainer;
161135

162136
updateSnapShotTree();
163137
// send the initial snapshot once the content script has started up
164138
window.addEventListener('message', ({ data: { action } }) => {
165-
if (action === 'contentScriptStarted') { // runs once on initial page load
166-
// console.log("in window.addEL")
167-
console.log('page running');
168-
sendSnapshot();
169-
}
139+
if (action === 'contentScriptStarted') sendSnapshot();
170140
});
171141
};
172142
};

package/timeJump.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ module.exports = (origin, mode) => {
2828
let index = 0;
2929
const hooks = returnState();
3030
// while loop through the memoize tree
31-
while (current && current.queue) {
31+
while (current) {
3232
current.queue.dispatch(target.state[hooks[index]]);
3333
// Reassign the current value
3434
current = current.next;

0 commit comments

Comments
 (0)