Skip to content

Commit

Permalink
Pass Suspense config to startTransition
Browse files Browse the repository at this point in the history
...instead of `useTransition`.

This avoids the problem of having to bind the config object to
`startTransition`, invalidating downstream memoizations.
  • Loading branch information
acdlite committed Nov 7, 2019
1 parent 35280c5 commit af4855c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 54 deletions.
54 changes: 19 additions & 35 deletions packages/react-reconciler/src/ReactFiberHooks.js
Expand Up @@ -1172,50 +1172,34 @@ function updateDeferredValue<T>(
return prevValue;
}

function startTransition(setPending, callback, config) {
setPending(true);
Scheduler.unstable_next(() => {
const previousConfig = ReactCurrentBatchConfig.suspense;
ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
try {
setPending(false);
callback();
} finally {
ReactCurrentBatchConfig.suspense = previousConfig;
}
});
}

function mountTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
const [isPending, setPending] = mountState(false);
const startTransition = mountCallback(
callback => {
setPending(true);
Scheduler.unstable_next(() => {
const previousConfig = ReactCurrentBatchConfig.suspense;
ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
try {
setPending(false);
callback();
} finally {
ReactCurrentBatchConfig.suspense = previousConfig;
}
});
},
[config, isPending],
);
return [startTransition, isPending];
const startTransitionRef = mountRef(startTransition.bind(null, setPending));
return [startTransitionRef.current, isPending];
}

function updateTransition(
config: SuspenseConfig | void | null,
): [(() => void) => void, boolean] {
const [isPending, setPending] = updateState(false);
const startTransition = updateCallback(
callback => {
setPending(true);
Scheduler.unstable_next(() => {
const previousConfig = ReactCurrentBatchConfig.suspense;
ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
try {
setPending(false);
callback();
} finally {
ReactCurrentBatchConfig.suspense = previousConfig;
}
});
},
[config, isPending],
);
return [startTransition, isPending];
const [isPending] = updateState(false);
const startTransitionRef = updateRef();
return [startTransitionRef.current, isPending];
}

function dispatchAction<S, A>(
Expand Down
Expand Up @@ -1977,16 +1977,18 @@ describe('ReactHooksWithNoopRenderer', () => {
it.experimental(
'delays showing loading state until after timeout',
async () => {
const SUSPENSE_CONFIG = {
timeoutMs: 1000,
};

let transition;
function App() {
const [show, setShow] = useState(false);
const [startTransition, isPending] = useTransition({
timeoutMs: 1000,
});
const [startTransition, isPending] = useTransition();
transition = () => {
startTransition(() => {
setShow(true);
});
}, SUSPENSE_CONFIG);
};
return (
<Suspense
Expand Down Expand Up @@ -2043,17 +2045,19 @@ describe('ReactHooksWithNoopRenderer', () => {
it.experimental(
'delays showing loading state until after busyDelayMs + busyMinDurationMs',
async () => {
const SUSPENSE_CONFIG = {
busyDelayMs: 1000,
busyMinDurationMs: 2000,
};

let transition;
function App() {
const [show, setShow] = useState(false);
const [startTransition, isPending] = useTransition({
busyDelayMs: 1000,
busyMinDurationMs: 2000,
});
const [startTransition, isPending] = useTransition();
transition = () => {
startTransition(() => {
setShow(true);
});
}, SUSPENSE_CONFIG);
};
return (
<Suspense
Expand Down Expand Up @@ -2113,13 +2117,15 @@ describe('ReactHooksWithNoopRenderer', () => {
);

it.experimental('always returns the same startTransition', async () => {
const SUSPENSE_CONFIG = {
busyDelayMs: 1000,
busyMinDurationMs: 2000,
};

let transition;
function App() {
const [step, setStep] = useState(0);
const [startTransition, isPending] = useTransition({
busyDelayMs: 1000,
busyMinDurationMs: 2000,
});
const [startTransition, isPending] = useTransition();
// Log whenever startTransition changes
useEffect(
() => {
Expand All @@ -2130,7 +2136,7 @@ describe('ReactHooksWithNoopRenderer', () => {
transition = () => {
startTransition(() => {
setStep(n => n + 1);
});
}, SUSPENSE_CONFIG);
};
return (
<Suspense fallback={<Text text="Loading..." />}>
Expand Down Expand Up @@ -2175,12 +2181,12 @@ describe('ReactHooksWithNoopRenderer', () => {
});

it.experimental(
'can update suspense config (without changing startTransition)',
'can pass different suspense configs per transition',
async () => {
let transition;
function App({timeoutMs}) {
const [step, setStep] = useState(0);
const [startTransition, isPending] = useTransition({timeoutMs});
const [startTransition, isPending] = useTransition();
// Log whenever startTransition changes
useEffect(
() => {
Expand All @@ -2189,9 +2195,12 @@ describe('ReactHooksWithNoopRenderer', () => {
[startTransition],
);
transition = () => {
startTransition(() => {
setStep(n => n + 1);
});
startTransition(
() => {
setStep(n => n + 1);
},
{timeoutMs},
);
};
return (
<Suspense fallback={<Text text="Loading..." />}>
Expand Down

0 comments on commit af4855c

Please sign in to comment.