Skip to content

Commit ef790da

Browse files
authored
Merge pull request #28 from crperezt/byebyenpm
Fixing bugs with hooks components state.
2 parents b9d01bc + 540cd9d commit ef790da

File tree

1 file changed

+30
-43
lines changed

1 file changed

+30
-43
lines changed

dev-reactime/linkFiber.js

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ const componentActionsRecord = require('./masterState');
4646

4747
module.exports = (snap, mode) => {
4848
let fiberRoot = null;
49-
let astHooks;
50-
let concurrent = false; // flag to check if we are in concurrent mode
5149

5250
async function sendSnapshot() {
5351
// Don't send messages while jumping or while paused
@@ -68,14 +66,14 @@ module.exports = (snap, mode) => {
6866
// Carlos: Injects instrumentation to update our state tree every time
6967
// a hooks component changes state
7068
function traverseHooks(memoizedState) {
71-
const hooksComponents = [];
69+
const hooksStates = [];
7270
while (memoizedState && memoizedState.queue) {
7371
// Carlos: these two are legacy comments, we should look into them later
7472
// prevents useEffect from crashing on load
7573
// if (memoizedState.next.queue === null) { // prevents double pushing snapshot updates
7674
if (memoizedState.memoizedState) {
7775
console.log('memoizedState in traverseHooks is:', memoizedState);
78-
hooksComponents.push({
76+
hooksStates.push({
7977
component: memoizedState.queue,
8078
state: memoizedState.memoizedState,
8179
});
@@ -84,7 +82,7 @@ module.exports = (snap, mode) => {
8482
memoizedState = memoizedState.next !== memoizedState
8583
? memoizedState.next : null;
8684
}
87-
return hooksComponents;
85+
return hooksStates;
8886
}
8987

9088
// Carlos: This runs after EVERY Fiber commit. It creates a new snapshot,
@@ -94,7 +92,6 @@ module.exports = (snap, mode) => {
9492
if (!currentFiber) return null;
9593
if (!tree) return tree;
9694

97-
9895
// These have the newest state. We update state and then
9996
// called updateSnapshotTree()
10097
const {
@@ -113,39 +110,45 @@ module.exports = (snap, mode) => {
113110
let newState = null;
114111
let componentData = {};
115112
let componentFound = false;
116-
// Check if node is a stateful component
113+
114+
// Check if node is a stateful setState component
117115
if (stateNode && stateNode.state && (tag === 0 || tag === 1)) {
118116
// Save component's state and setState() function to our record for future
119117
// time-travel state changing. Add record index to snapshot so we can retrieve.
120118
componentData.index = componentActionsRecord.saveNew(stateNode.state, stateNode);
121-
newState = stateNode.state;
119+
newState.state = stateNode.state;
122120
componentFound = true;
123-
// tree.appendToChild(stateNode.state, elementType.name, index); // Add component to tree
124-
} else if (tag === 0 || tag === 1) {
125-
// grab stateless components here
126-
newState = 'stateless';
127-
// tree.appendChild({}, elementType.name) // Add component to tree
128121
}
129122

130-
// Check if node is a hooks function
123+
// Check if node is a hooks useState function
131124
let hooksIndex;
132125
if (memoizedState && (tag === 0 || tag === 1 || tag === 10)) {
133126
if (memoizedState.queue) {
134-
const hooksComponents = traverseHooks(memoizedState);
135-
hooksComponents.forEach(c => {
136-
hooksIndex = componentActionsRecord.saveNew(c.state, c.component);
137-
if (newState.hooksState) {
138-
newState.hooksState.push([c.state, hooksIndex]);
127+
// Hooks states are stored as a linked list using memoizedState.next,
128+
// so we must traverse through the list and get the states.
129+
// We then store them along with the corresponding memoizedState.queue,
130+
// which includes the dispatch() function we use to change their state.
131+
const hooksStates = traverseHooks(memoizedState);
132+
hooksStates.forEach(state => {
133+
hooksIndex = componentActionsRecord.saveNew(state.state, state.component);
134+
if (newState && newState.hooksState) {
135+
newState.hooksState.push([state.state, hooksIndex]);
136+
} else if (newState) {
137+
newState.hooksState = [[state.state, hooksIndex]];
139138
} else {
140-
newState.hooksState = [[c.state, hooksIndex]];
139+
newState = { hooksState: [[state.state, hooksIndex]] };
141140
}
142141
componentFound = true;
143-
// newState = { ...newState, hooksState: c.state };
144-
// tree.appendSibling(c.state, elementType.name ? elementType.name : 'nameless', index);
145142
});
146143
}
147144
}
148145

146+
// This grabs stateless components
147+
if (!componentFound && (tag === 0 || tag === 1)) {
148+
newState = 'stateless';
149+
}
150+
151+
// Adds performance metrics to the component data
149152
componentData = {
150153
...componentData,
151154
actualDuration,
@@ -162,6 +165,9 @@ module.exports = (snap, mode) => {
162165

163166
// Recurse on children
164167
if (child) {
168+
// If this node had state we appended to the children array,
169+
// so attach children to the newly appended child.
170+
// Otherwise, attach children to this same node.
165171
if (tree.children.length > 0) {
166172
createTree(child, tree.children[tree.children.length - 1]);
167173
} else {
@@ -176,43 +182,24 @@ module.exports = (snap, mode) => {
176182

177183
// ! BUG: skips 1st hook click
178184
function updateSnapShotTree() {
179-
/* let current;
180-
// If concurrent mode, grab current.child
181-
if (concurrent) {
182-
// we need a way to wait for current child to populate
183-
const promise = new Promise((resolve, reject) => {
184-
setTimeout(() => resolve(fiberRoot.current.child), 400);
185-
});
186-
current = await promise;
187-
current = fiberRoot.current.child;
188-
} else {
189-
current = fiberRoot.current;
190-
} */
191-
const { current } = fiberRoot; // Carlos: get rid of concurrent mode for now
192-
193-
// console.log('FIBER COMMITTED, new fiber is:', util.inspect(current, false, 4));
194-
// fs.appendFile('fiberlog.txt', util.inspect(current, false, 10));
195-
snap.tree = createTree(current); // Carlos: pass new hooks state here?
185+
const { current } = fiberRoot;
186+
snap.tree = createTree(current);
196187
}
197188

198189
return async container => {
199190
// Point fiberRoot to FiberRootNode
200191
if (container._internalRoot) {
201192
fiberRoot = container._internalRoot;
202-
concurrent = true;
203193
} else {
204194
const {
205195
_reactRootContainer: { _internalRoot },
206196
_reactRootContainer,
207197
} = container;
208198
// Only assign internal root if it actually exists
209199
fiberRoot = _internalRoot || _reactRootContainer;
210-
// console.log('_reactRootContainer is:', _reactRootContainer);
211-
// console.log('linkFiber.js, fiberRoot:', fiberRoot);
212200
}
213201
const devTools = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
214202
const reactInstance = devTools ? devTools.renderers.get(1) : null;
215-
const overrideHookState = reactInstance ? reactInstance.overrideHookState : null;
216203

217204
if (reactInstance && reactInstance.version) {
218205
devTools.onCommitFiberRoot = (function (original) {

0 commit comments

Comments
 (0)