Skip to content
Created: September 25, 2025

If we start from "What will happen if global variables are not used?", you will find that this is an almost forced choice.

Hooks uses global variables, not to be lazy, but to ensure: render is rerunable, interruptible, zero intrusive, and zero compilation cost.

1. What "global variables" are used by Hooks? ​

There are only these cores:

ts
let currentlyRenderingFiber = null
let workInProgressHook = null
let currentHook = null

Add one more:

ts
ReactCurrentDispatcher.current

👉 All Hooks work through these "implicit contexts"

2. Why can’t it be passed by parameters? ​

An ideal API might be:

ts
function useState(ctx, initial) { ... }

function App(props, ctx) {
  const [a, setA] = useState(ctx, 0)
}

Or more "implicitly":

ts
function App(props, ctx = useHooksContext()) { ... }

Does it look clean? ​

3. The first fatal problem of parameter passing: API is polluted ​

One of React's core goals is to:

Component function = ordinary JS function

ts
Component(props) → JSX

If parameters are introduced:

  • Every component needs to receive ctx
  • Each Hook must be passed explicitly
  • User mental complexity skyrockets

👉 This directly goes against React’s design philosophy

4. The second fatal problem: render cannot be "transparently rerun" ​

The core premise of Fiber is:

render is a discardable, retryable pure function

If the Hook context relies on parameters:

ts
render(Component, ctx)

You must ensure:

  • ctx is consistent across multiple renders
  • ctx lifecycle synchronized with Fiber
  • ctx traceable on interrupt/resume

👉 You are actually "Handwriting Fiber"

5. The third fatal problem: "zero compilation" cannot be achieved ​

If global variables are not used, the only remaining options are:

1️⃣ Compile time injection ​

ts
useState() 
↓ 编译
useState(__hookCtx, ...)

This means:

  • A compiler is required
  • DSL must be locked
  • Breaking JS direct writing

👉 React explicitly rejects this path

6. The "hidden advantage" of global variables: interrupt friendly ​

You already understood Fiber’s execution model:

ts
renderWithHooks
  set currentlyRenderingFiber
  execute Component()
  clear globals

What happens when there is an interruption? ​

  • render is discarded
  • Global variables are reset directly
  • No semi-finished product will be left

If it is a parameter:

  • You want to save ctx
  • To roll back
  • to replay

👉 Complexity increases exponentially

7. Why is the “overall situation” safe? ​

This is an easily misunderstood point.

Not the "real global state" ​

Instead:

"Dynamic scope" during render

ts
renderWithHooks() {
  set globals
  Component()
  clear globals
}
  • single thread
  • Only render one Fiber at the same time
  • No concurrent write conflicts

👉 logically safe

8. Vue effect comparison (helping you align) ​

Vue3React
activeEffectcurrentlyRenderingFiber
effect(fn)renderWithHooks
track implicitHooks implicit
Compilation enhancementsRuntime conventions

👉 Both are "implicit contexts", just in different positions.

9. What will happen if global variables are not used forcibly? ​

You will get a frame:

  • Component signature is tainted
  • Hook API is complex
  • render is no longer a pure function
  • Interruption/concurrency cost explosion
  • Compiler must be introduced

👉 This is not React anymore

10. Summary ​

Hooks uses global variables in order to use "minimum runtime cost". In exchange for "maximum scheduling freedom" and "the cleanest user API".

This isn't an implementation detail, it's a core design choice.