Skip to content

Commit

Permalink
create hot path for unmounting a tree of context (#4396)
Browse files Browse the repository at this point in the history
  • Loading branch information
JoviDeCroock committed May 22, 2024
1 parent 77d941c commit 8d228d2
Showing 1 changed file with 8 additions and 16 deletions.
24 changes: 8 additions & 16 deletions src/create-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,19 @@ export function createContext(defaultValue, contextId) {
/** @type {FunctionComponent} */
Provider(props) {
if (!this.getChildContext) {
/** @type {Component[]} */
/** @type {Component[] | null} */
let subs = [];
let ctx = {};
ctx[contextId] = this;

this.getChildContext = () => ctx;

this.componentWillUnmount = () => {
subs = null;
};

this.shouldComponentUpdate = function (_props) {
if (this.props.value !== _props.value) {
// I think the forced value propagation here was only needed when `options.debounceRendering` was being bypassed:
// https://github.com/preactjs/preact/commit/4d339fb803bea09e9f198abf38ca1bf8ea4b7771#diff-54682ce380935a717e41b8bfc54737f6R358
// In those cases though, even with the value corrected, we're double-rendering all nodes.
// It might be better to just tell folks not to use force-sync mode.
// Currently, using `useContext()` in a class component will overwrite its `this.context` value.
// subs.some(c => {
// c.context = _props.value;
// enqueueRender(c);
// });

// subs.some(c => {
// c.context[contextId] = _props.value;
// enqueueRender(c);
// });
subs.some(c => {
c._force = true;
enqueueRender(c);
Expand All @@ -52,7 +42,9 @@ export function createContext(defaultValue, contextId) {
subs.push(c);
let old = c.componentWillUnmount;
c.componentWillUnmount = () => {
subs.splice(subs.indexOf(c), 1);
if (subs) {
subs.splice(subs.indexOf(c), 1);
}
if (old) old.call(c);
};
};
Expand Down

0 comments on commit 8d228d2

Please sign in to comment.