|
1 | | -import { useState } from 'react'; |
2 | 1 | import { Dispatch } from 'react/src/currentDispatcher'; |
3 | 2 | import { Dispatcher } from 'react/src/currentDispatcher'; |
| 3 | +import currentBatchConfig from 'react/src/currentBatchConfig'; |
4 | 4 | import internals from 'shared/internals'; |
5 | 5 | import { Action } from 'shared/ReactTypes'; |
6 | 6 | import { FiberNode } from './fiber'; |
@@ -80,12 +80,14 @@ export function renderWithHooks(wip: FiberNode, lane: Lane) { |
80 | 80 |
|
81 | 81 | const HooksDispatcherOnMount: Dispatcher = { |
82 | 82 | useState: mountState, |
83 | | - useEffect: mountEffect |
| 83 | + useEffect: mountEffect, |
| 84 | + useTransition: mountTransition |
84 | 85 | }; |
85 | 86 |
|
86 | 87 | const HooksDispatcherOnUpdate: Dispatcher = { |
87 | 88 | useState: updateState, |
88 | | - useEffect: updateEffect |
| 89 | + useEffect: updateEffect, |
| 90 | + useTransition: updateTransition |
89 | 91 | }; |
90 | 92 |
|
91 | 93 | function mountEffect(create: EffectCallback | void, deps: EffectDeps | void) { |
@@ -215,17 +217,17 @@ function updateState<State>(): [State, Dispatch<State>] { |
215 | 217 | // 保存在current中 |
216 | 218 | current.baseQueue = pending; |
217 | 219 | queue.shared.pending = null; |
| 220 | + } |
218 | 221 |
|
219 | | - if (baseQueue !== null) { |
220 | | - const { |
221 | | - memoizedState, |
222 | | - baseQueue: newBaseQueue, |
223 | | - baseState: newBaseState |
224 | | - } = processUpdateQueue(baseState, baseQueue, renderLane); |
225 | | - hook.memoizedState = memoizedState; |
226 | | - hook.baseState = newBaseState; |
227 | | - hook.baseQueue = newBaseQueue; |
228 | | - } |
| 222 | + if (baseQueue !== null) { |
| 223 | + const { |
| 224 | + memoizedState, |
| 225 | + baseQueue: newBaseQueue, |
| 226 | + baseState: newBaseState |
| 227 | + } = processUpdateQueue(baseState, baseQueue, renderLane); |
| 228 | + hook.memoizedState = memoizedState; |
| 229 | + hook.baseState = newBaseState; |
| 230 | + hook.baseQueue = newBaseQueue; |
229 | 231 | } |
230 | 232 |
|
231 | 233 | return [hook.memoizedState, queue.dispatch as Dispatch<State>]; |
@@ -295,13 +297,40 @@ function mountState<State>( |
295 | 297 | const queue = createUpdateQueue<State>(); |
296 | 298 | hook.updateQueue = queue; |
297 | 299 | hook.memoizedState = memoizedState; |
| 300 | + hook.baseState = memoizedState; |
298 | 301 |
|
299 | 302 | // @ts-ignore |
300 | 303 | const dispatch = dispatchSetState.bind(null, currentlyRenderingFiber, queue); |
301 | 304 | queue.dispatch = dispatch; |
302 | 305 | return [memoizedState, dispatch]; |
303 | 306 | } |
304 | 307 |
|
| 308 | +function mountTransition(): [boolean, (callback: () => void) => void] { |
| 309 | + const [isPending, setPending] = mountState(false); |
| 310 | + const hook = mountWorkInProgresHook(); |
| 311 | + const start = startTransition.bind(null, setPending); |
| 312 | + hook.memoizedState = start; |
| 313 | + return [isPending, start]; |
| 314 | +} |
| 315 | + |
| 316 | +function updateTransition(): [boolean, (callback: () => void) => void] { |
| 317 | + const [isPending] = updateState(); |
| 318 | + const hook = updateWorkInProgresHook(); |
| 319 | + const start = hook.memoizedState; |
| 320 | + return [isPending as boolean, start]; |
| 321 | +} |
| 322 | + |
| 323 | +function startTransition(setPending: Dispatch<boolean>, callback: () => void) { |
| 324 | + setPending(true); |
| 325 | + const prevTransition = currentBatchConfig.transition; |
| 326 | + currentBatchConfig.transition = 1; |
| 327 | + |
| 328 | + callback(); |
| 329 | + setPending(false); |
| 330 | + |
| 331 | + currentBatchConfig.transition = prevTransition; |
| 332 | +} |
| 333 | + |
305 | 334 | function dispatchSetState<State>( |
306 | 335 | fiber: FiberNode, |
307 | 336 | updateQueue: UpdateQueue<State>, |
|
0 commit comments