Skip to content

Commit 17cf982

Browse files
authored
Merge pull request #5 from oslabs-beta/hooks-implementation
Latest Hooks implementation
2 parents 013cee4 + 7c5ad42 commit 17cf982

File tree

2 files changed

+93
-18
lines changed

2 files changed

+93
-18
lines changed

package/linkFiber.js

Lines changed: 88 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable func-names */
12
/* eslint-disable no-use-before-define */
23
/* eslint-disable no-param-reassign */
34
// links component state tree to library
@@ -9,14 +10,17 @@ module.exports = (snap, mode) => {
910

1011
function sendSnapshot() {
1112
// don't send messages while jumping or while paused
13+
// DEV: So that when we are jumping to an old snapshot it wouldn't think we want to create new snapshots
1214
if (mode.jumping || mode.paused) return;
1315
const payload = snap.tree.getCopy();
16+
// console.log('payload', payload);
1417
window.postMessage({
1518
action: 'recordSnap',
1619
payload,
1720
});
1821
}
1922

23+
// DEV: This is how we know when a change has happened (by injecting an event listener to every component's setState functionality). Will need to create a separate one for useState components
2024
function changeSetState(component) {
2125
// check that setState hasn't been changed yet
2226
if (component.setState.linkFiberChanged) return;
@@ -40,11 +44,31 @@ module.exports = (snap, mode) => {
4044
component.setState.linkFiberChanged = true;
4145
}
4246

47+
// Helper function to traverse through the memoized state
48+
function traverseHooks(memoizedState) {
49+
// Declare variables and assigned to 0th index and an empty object, respectively
50+
let index = 0;
51+
const memoizedObj = {};
52+
// while memoizedState is truthy, save the value to the object
53+
while (memoizedState) {
54+
// Increment the index by 1
55+
memoizedObj[`useState${index += 1}`] = memoizedState.memoizedState;
56+
// Reassign memoizedState to its next value
57+
memoizedState = memoizedState.next;
58+
}
59+
return memoizedObj;
60+
}
61+
4362
function createTree(currentFiber, tree = new Tree('root')) {
4463
if (!currentFiber) return tree;
4564
// We have to figure out which properties to destructure from currentFiber
46-
// To support hooks and Context API
47-
const { sibling, stateNode, child } = currentFiber;
65+
// To support hooks and Context API
66+
const {
67+
sibling,
68+
stateNode,
69+
child,
70+
memoizedState,
71+
} = currentFiber;
4872

4973
let nextTree = tree;
5074
// check if stateful component
@@ -54,8 +78,16 @@ module.exports = (snap, mode) => {
5478
// change setState functionality
5579
changeSetState(stateNode);
5680
}
57-
// Need to check if functional component AND uses hooks
58-
81+
// Check if the component uses hooks
82+
// TODO: Refactor the conditionals - think about the edge case where a stateful
83+
// component might have a key called 'baseState' in the state
84+
if (memoizedState && memoizedState.hasOwnProperty('baseState')) {
85+
// console.log('The memoizedState is: ', memoizedState);
86+
const result = traverseHooks(memoizedState);
87+
console.log('This is the result of calling traverseHooks:', result);
88+
nextTree = tree.appendChild(result);
89+
}
90+
5991
// iterate through siblings
6092
createTree(sibling, tree);
6193
// iterate through children
@@ -65,22 +97,61 @@ module.exports = (snap, mode) => {
6597
}
6698

6799
function updateSnapShotTree() {
100+
// console.log('fiberRoot', fiberRoot);
68101
const { current } = fiberRoot;
102+
console.log('current', current);
69103
snap.tree = createTree(current);
70104
}
71105

72-
return container => {
73-
const {
74-
_reactRootContainer: { _internalRoot },
75-
_reactRootContainer,
76-
} = container;
77-
// only assign internal root if it actually exists
78-
fiberRoot = _internalRoot || _reactRootContainer;
79-
updateSnapShotTree();
106+
// return container => {
107+
// // console.log('Container', container);
108+
// const {
109+
// _reactRootContainer: { _internalRoot },
110+
// _reactRootContainer,
111+
// } = container;
112+
// // console.log('Root container', _reactRootContainer);
113+
// // only assign internal root if it actually exists
114+
// fiberRoot = _internalRoot || _reactRootContainer;
115+
// updateSnapShotTree();
80116

81-
// send the initial snapshot once the content script has started up
82-
window.addEventListener('message', ({ data: { action } }) => {
83-
if (action === 'contentScriptStarted') sendSnapshot();
84-
});
117+
// // send the initial snapshot once the content script has started up
118+
// window.addEventListener('message', ({ data: { action } }) => {
119+
// if (action === 'contentScriptStarted') sendSnapshot();
120+
// });
121+
// };
122+
123+
return {
124+
main(container) {
125+
// console.log('Container', container);
126+
const {
127+
_reactRootContainer: { _internalRoot },
128+
_reactRootContainer,
129+
} = container;
130+
// console.log('Root container', _reactRootContainer);
131+
// only assign internal root if it actually exists
132+
fiberRoot = _internalRoot || _reactRootContainer;
133+
updateSnapShotTree();
134+
135+
// send the initial snapshot once the content script has started up
136+
window.addEventListener('message', ({ data: { action } }) => {
137+
if (action === 'contentScriptStarted') sendSnapshot();
138+
});
139+
},
140+
changeUseState(useState) {
141+
return function (initial) {
142+
// running the original useState and storing its result (state and dispatch function)
143+
const toReturn = useState(initial);
144+
console.log(toReturn);
145+
// storing the original dispatch function definition somewhere
146+
const oldDispatch = toReturn[1];
147+
// redefining the dispatch function so we can inject our code
148+
toReturn[1] = function (callback) {
149+
oldDispatch(callback);
150+
updateSnapShotTree();
151+
sendSnapshot();
152+
};
153+
return toReturn;
154+
};
155+
},
85156
};
86-
};
157+
};

package/tree.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ class Tree {
1414
this.name = name;
1515
}
1616
this.children = [];
17+
// DEV: Added print() for debugging purposes
18+
// this.print();
1719
}
1820

1921
appendChild(component) {
@@ -26,7 +28,7 @@ class Tree {
2628
getCopy(copy = new Tree('root', true)) {
2729
// copy state of children
2830
copy.children = this.children.map(
29-
child => new Tree(child.component.state, true, child.component.constructor.name),
31+
child => new Tree(child.component.state || child.component, true, child.component.constructor.name),
3032
);
3133

3234
// copy children's children recursively
@@ -35,10 +37,12 @@ class Tree {
3537
}
3638

3739
// print out the tree in the console
40+
// DEV: Process may be different for useState components
3841
// BUG FIX: Don't print the Router as a component
3942
// Change how the children are printed
4043
print() {
4144
const children = ['children: '];
45+
// DEV: What should we push instead for components using hooks (it wouldn't be state)
4246
this.children.forEach(child => {
4347
children.push(child.state || child.component.state);
4448
});

0 commit comments

Comments
 (0)