Recover from render errors by remounting root

Summary: This updates the renderer and Fresh packages to pull in the new error handling behavior. The new feature is that roots that errored on last save get remounted after an edit. This allows much faster iteration in the Fast Refresh mode as you don't need to do a full reload after typos.

Reviewed By: bvaughn

Differential Revision: D15967396

fbshipit-source-id: 96a82e6a4e00a8cb636d7bca037a1a43552a4cd2
This commit is contained in:
Dan Abramov 2019-06-24 13:49:01 -07:00 коммит произвёл Facebook Github Bot
Родитель cf7813a625
Коммит 0a17699fd5
14 изменённых файлов: 125 добавлений и 17 удалений

Просмотреть файл

@ -5074,7 +5074,8 @@ function injectInternals(internals) {
var rendererID = hook.inject(internals);
// We have successfully injected, so now it is safe to set up hooks.
onCommitFiberRoot = catchErrors(function(root) {
return hook.onCommitFiberRoot(rendererID, root);
var didError = (root.current.effectTag & DidCapture) === DidCapture;
hook.onCommitFiberRoot(rendererID, root, undefined, didError);
});
onCommitFiberUnmount = catchErrors(function(fiber) {
return hook.onCommitFiberUnmount(rendererID, fiber);
@ -18287,6 +18288,19 @@ var scheduleRefresh = function(root, update) {
}
};
var scheduleRoot = function(root, element) {
{
if (root.context !== emptyContextObject) {
// Super edge case: root has a legacy _renderSubtree context
// but we don't know the parentComponent so we can't pass it.
// Just ignore. We'll delete this with _renderSubtree code path later.
return;
}
flushPassiveEffects();
updateContainerAtExpirationTime(element, root, null, Sync, null);
}
};
function scheduleFibersWithFamiliesRecursively(
fiber,
updatedFamilies,
@ -19469,6 +19483,7 @@ function injectIntoDevTools(devToolsConfig) {
// React Refresh
findHostInstancesForRefresh: findHostInstancesForRefresh,
scheduleRefresh: scheduleRefresh,
scheduleRoot: scheduleRoot,
setRefreshHandler: setRefreshHandler
})
);

Просмотреть файл

@ -5070,7 +5070,8 @@ function injectInternals(internals) {
var rendererID = hook.inject(internals);
// We have successfully injected, so now it is safe to set up hooks.
onCommitFiberRoot = catchErrors(function(root) {
return hook.onCommitFiberRoot(rendererID, root);
var didError = (root.current.effectTag & DidCapture) === DidCapture;
hook.onCommitFiberRoot(rendererID, root, undefined, didError);
});
onCommitFiberUnmount = catchErrors(function(fiber) {
return hook.onCommitFiberUnmount(rendererID, fiber);
@ -18283,6 +18284,19 @@ var scheduleRefresh = function(root, update) {
}
};
var scheduleRoot = function(root, element) {
{
if (root.context !== emptyContextObject) {
// Super edge case: root has a legacy _renderSubtree context
// but we don't know the parentComponent so we can't pass it.
// Just ignore. We'll delete this with _renderSubtree code path later.
return;
}
flushPassiveEffects();
updateContainerAtExpirationTime(element, root, null, Sync, null);
}
};
function scheduleFibersWithFamiliesRecursively(
fiber,
updatedFamilies,
@ -19465,6 +19479,7 @@ function injectIntoDevTools(devToolsConfig) {
// React Refresh
findHostInstancesForRefresh: findHostInstancesForRefresh,
scheduleRefresh: scheduleRefresh,
scheduleRoot: scheduleRoot,
setRefreshHandler: setRefreshHandler
})
);

Просмотреть файл

@ -1736,7 +1736,12 @@ function injectInternals(internals) {
try {
var rendererID = hook.inject(internals);
onCommitFiberRoot = catchErrors(function(root) {
return hook.onCommitFiberRoot(rendererID, root);
hook.onCommitFiberRoot(
rendererID,
root,
void 0,
64 === (root.current.effectTag & 64)
);
});
onCommitFiberUnmount = catchErrors(function(fiber) {
return hook.onCommitFiberUnmount(rendererID, fiber);
@ -6960,6 +6965,7 @@ var roots = new Map(),
},
findHostInstancesForRefresh: null,
scheduleRefresh: null,
scheduleRoot: null,
setRefreshHandler: null
})
);

Просмотреть файл

@ -1736,7 +1736,12 @@ function injectInternals(internals) {
try {
var rendererID = hook.inject(internals);
onCommitFiberRoot = catchErrors(function(root) {
return hook.onCommitFiberRoot(rendererID, root);
hook.onCommitFiberRoot(
rendererID,
root,
void 0,
64 === (root.current.effectTag & 64)
);
});
onCommitFiberUnmount = catchErrors(function(fiber) {
return hook.onCommitFiberUnmount(rendererID, fiber);
@ -6960,6 +6965,7 @@ var roots = new Map(),
},
findHostInstancesForRefresh: null,
scheduleRefresh: null,
scheduleRoot: null,
setRefreshHandler: null
})
);

Просмотреть файл

@ -1738,7 +1738,12 @@ function injectInternals(internals) {
try {
var rendererID = hook.inject(internals);
onCommitFiberRoot = catchErrors(function(root) {
return hook.onCommitFiberRoot(rendererID, root);
hook.onCommitFiberRoot(
rendererID,
root,
void 0,
64 === (root.current.effectTag & 64)
);
});
onCommitFiberUnmount = catchErrors(function(fiber) {
return hook.onCommitFiberUnmount(rendererID, fiber);
@ -7197,6 +7202,7 @@ var roots = new Map(),
},
findHostInstancesForRefresh: null,
scheduleRefresh: null,
scheduleRoot: null,
setRefreshHandler: null
})
);

Просмотреть файл

@ -1738,7 +1738,12 @@ function injectInternals(internals) {
try {
var rendererID = hook.inject(internals);
onCommitFiberRoot = catchErrors(function(root) {
return hook.onCommitFiberRoot(rendererID, root);
hook.onCommitFiberRoot(
rendererID,
root,
void 0,
64 === (root.current.effectTag & 64)
);
});
onCommitFiberUnmount = catchErrors(function(fiber) {
return hook.onCommitFiberUnmount(rendererID, fiber);
@ -7197,6 +7202,7 @@ var roots = new Map(),
},
findHostInstancesForRefresh: null,
scheduleRefresh: null,
scheduleRoot: null,
setRefreshHandler: null
})
);

Просмотреть файл

@ -5389,7 +5389,8 @@ function injectInternals(internals) {
var rendererID = hook.inject(internals);
// We have successfully injected, so now it is safe to set up hooks.
onCommitFiberRoot = catchErrors(function(root) {
return hook.onCommitFiberRoot(rendererID, root);
var didError = (root.current.effectTag & DidCapture) === DidCapture;
hook.onCommitFiberRoot(rendererID, root, undefined, didError);
});
onCommitFiberUnmount = catchErrors(function(fiber) {
return hook.onCommitFiberUnmount(rendererID, fiber);
@ -18601,6 +18602,19 @@ var scheduleRefresh = function(root, update) {
}
};
var scheduleRoot = function(root, element) {
{
if (root.context !== emptyContextObject) {
// Super edge case: root has a legacy _renderSubtree context
// but we don't know the parentComponent so we can't pass it.
// Just ignore. We'll delete this with _renderSubtree code path later.
return;
}
flushPassiveEffects();
updateContainerAtExpirationTime(element, root, null, Sync, null);
}
};
function scheduleFibersWithFamiliesRecursively(
fiber,
updatedFamilies,
@ -19783,6 +19797,7 @@ function injectIntoDevTools(devToolsConfig) {
// React Refresh
findHostInstancesForRefresh: findHostInstancesForRefresh,
scheduleRefresh: scheduleRefresh,
scheduleRoot: scheduleRoot,
setRefreshHandler: setRefreshHandler
})
);

Просмотреть файл

@ -5385,7 +5385,8 @@ function injectInternals(internals) {
var rendererID = hook.inject(internals);
// We have successfully injected, so now it is safe to set up hooks.
onCommitFiberRoot = catchErrors(function(root) {
return hook.onCommitFiberRoot(rendererID, root);
var didError = (root.current.effectTag & DidCapture) === DidCapture;
hook.onCommitFiberRoot(rendererID, root, undefined, didError);
});
onCommitFiberUnmount = catchErrors(function(fiber) {
return hook.onCommitFiberUnmount(rendererID, fiber);
@ -18597,6 +18598,19 @@ var scheduleRefresh = function(root, update) {
}
};
var scheduleRoot = function(root, element) {
{
if (root.context !== emptyContextObject) {
// Super edge case: root has a legacy _renderSubtree context
// but we don't know the parentComponent so we can't pass it.
// Just ignore. We'll delete this with _renderSubtree code path later.
return;
}
flushPassiveEffects();
updateContainerAtExpirationTime(element, root, null, Sync, null);
}
};
function scheduleFibersWithFamiliesRecursively(
fiber,
updatedFamilies,
@ -19779,6 +19793,7 @@ function injectIntoDevTools(devToolsConfig) {
// React Refresh
findHostInstancesForRefresh: findHostInstancesForRefresh,
scheduleRefresh: scheduleRefresh,
scheduleRoot: scheduleRoot,
setRefreshHandler: setRefreshHandler
})
);

Просмотреть файл

@ -1772,7 +1772,12 @@ function injectInternals(internals) {
try {
var rendererID = hook.inject(internals);
onCommitFiberRoot = catchErrors(function(root) {
return hook.onCommitFiberRoot(rendererID, root);
hook.onCommitFiberRoot(
rendererID,
root,
void 0,
64 === (root.current.effectTag & 64)
);
});
onCommitFiberUnmount = catchErrors(function(fiber) {
return hook.onCommitFiberUnmount(rendererID, fiber);
@ -7190,6 +7195,7 @@ var roots = new Map(),
},
findHostInstancesForRefresh: null,
scheduleRefresh: null,
scheduleRoot: null,
setRefreshHandler: null
})
);

Просмотреть файл

@ -1772,7 +1772,12 @@ function injectInternals(internals) {
try {
var rendererID = hook.inject(internals);
onCommitFiberRoot = catchErrors(function(root) {
return hook.onCommitFiberRoot(rendererID, root);
hook.onCommitFiberRoot(
rendererID,
root,
void 0,
64 === (root.current.effectTag & 64)
);
});
onCommitFiberUnmount = catchErrors(function(fiber) {
return hook.onCommitFiberUnmount(rendererID, fiber);
@ -7190,6 +7195,7 @@ var roots = new Map(),
},
findHostInstancesForRefresh: null,
scheduleRefresh: null,
scheduleRoot: null,
setRefreshHandler: null
})
);

Просмотреть файл

@ -1774,7 +1774,12 @@ function injectInternals(internals) {
try {
var rendererID = hook.inject(internals);
onCommitFiberRoot = catchErrors(function(root) {
return hook.onCommitFiberRoot(rendererID, root);
hook.onCommitFiberRoot(
rendererID,
root,
void 0,
64 === (root.current.effectTag & 64)
);
});
onCommitFiberUnmount = catchErrors(function(fiber) {
return hook.onCommitFiberUnmount(rendererID, fiber);
@ -7430,6 +7435,7 @@ var roots = new Map(),
},
findHostInstancesForRefresh: null,
scheduleRefresh: null,
scheduleRoot: null,
setRefreshHandler: null
})
);

Просмотреть файл

@ -1774,7 +1774,12 @@ function injectInternals(internals) {
try {
var rendererID = hook.inject(internals);
onCommitFiberRoot = catchErrors(function(root) {
return hook.onCommitFiberRoot(rendererID, root);
hook.onCommitFiberRoot(
rendererID,
root,
void 0,
64 === (root.current.effectTag & 64)
);
});
onCommitFiberUnmount = catchErrors(function(fiber) {
return hook.onCommitFiberUnmount(rendererID, fiber);
@ -7430,6 +7435,7 @@ var roots = new Map(),
},
findHostInstancesForRefresh: null,
scheduleRefresh: null,
scheduleRoot: null,
setRefreshHandler: null
})
);

Просмотреть файл

@ -103,7 +103,7 @@
"promise": "^7.1.1",
"prop-types": "^15.7.2",
"react-devtools-core": "^3.6.0",
"react-refresh": "0.0.7",
"react-refresh": "0.0.8",
"regenerator-runtime": "^0.13.2",
"scheduler": "0.14.0",
"stacktrace-parser": "^0.1.3",

Просмотреть файл

@ -5925,10 +5925,10 @@ react-proxy@^1.1.7:
lodash "^4.6.1"
react-deep-force-update "^1.0.0"
react-refresh@0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.0.7.tgz#0d900c2fd605a89624e4ec79ec1ad786246e1f55"
integrity sha512-AOUyJUlII1ZcrOt5k72dkSleQeLwFOZqVvkMkZO4uLeU2Qsc2EEJN1MRyyHsnl9LHxBlVJ0gBnIFIJ0w8hsPhQ==
react-refresh@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.0.8.tgz#ee1083f08d32c99b52018660b7ba0242369359c8"
integrity sha512-Xs0garuWQugSMGq382tKn0dG5sIouCzxNb8I4I9A9A3ebRq+6Qgg+puDbFITe10s0vigIq5fm3m2j3oDRhkbnQ==
react-test-renderer@16.8.6:
version "16.8.6"