# React Const vs Function Component: Syntax Differences and When to Use Each

> Explore React const vs function component differences in hoisting refactoring and lexical this binding Learn when to use each for optimal React development

- Repository: [Meta/react](https://github.com/facebook/react)
- Tags: deep-dive
- Published: 2026-02-20

---

**Both function declarations and const arrow functions create identical React components at runtime, but they differ significantly in hoisting behavior, refactoring ergonomics, and lexical `this` binding.**

When working with the `facebook/react` repository, understanding the nuances of react const vs function component declarations helps teams write more maintainable code. While the React reconciler treats both styles identically during the render phase, JavaScript’s lexical scoping rules create practical differences that affect debugging, module organization, and future architectural changes.

## Hoisting Behavior and Definition Order

Function declarations are **hoisted** to the top of their scope, allowing you to reference the component before its definition appears in the file. This enables patterns like circular imports or forward references without temporal dead zone errors.

In [`packages/react/src/__tests__/ReactStrictMode-test.internal.js`](https://github.com/facebook/react/blob/main/packages/react/src/__tests__/ReactStrictMode-test.internal.js) at line 32, the React team uses function declarations that can be referenced anywhere in the module regardless of physical location.

Conversely, const-bound arrow functions are **not hoisted**. The variable exists only after the assignment expression executes, creating a temporal dead zone. Referencing a const component before its definition results in a runtime `ReferenceError`.

```javascript
// src/components/Circular.js
export default () => <Header />;   // OK – Header is hoisted

function Header() {
  return <h1>Header</h1>;
}

```

```javascript
// src/components/CircularConst.js
export default () => <Header />;   // ❌ Throws “Header is not defined”

const Header = () => <h1>Header</h1>;

```

## Debugging and Display Name Inference

React DevTools and error boundaries rely on **display names** to identify components in stack traces. Both declaration styles provide this metadata automatically, but through different mechanisms.

- **Function declarations**: React reads the `name` property of the function object directly.
- **Const arrows**: React infers the name from the variable identifier to which the arrow function is assigned.

In practice, both approaches yield readable labels in development. However, aggressive minifiers may mangle const variable names more destructively than function declarations, potentially obscuring component identities in production builds.

## Refactoring and Maintainability

The choice between syntaxes impacts long-term code evolution, particularly when migrating between component types.

### Migration to Class Components

Function declarations simplify conversion to class components because they already follow the structural pattern of methods. To convert `function MyComponent()` to a class, you only need to add `extends React.Component` and wrap the body in a `render()` method.

Converting a const arrow function requires rewriting the assignment into a class body and method definition, introducing more mechanical changes and potential merge conflicts.

### Inline and Callback Usage

Const arrow functions excel when defining **inline components** passed as props or rendered within map iterations. The concise syntax reduces boilerplate when the component is tightly coupled to its usage site, as seen in fixture applications like [`fixtures/fizz/src/App.js`](https://github.com/facebook/react/blob/main/fixtures/fizz/src/App.js) where lightweight utility components appear adjacent to their consumption.

## The `this` Binding Nuance

Arrow functions capture the lexical `this` of their surrounding scope, while function declarations receive their own `this` context (typically `undefined` in strict mode).

In React function components, `this` is never meaningful—hooks and closures replace instance state. However, arrow functions may **hide accidental `this` usage** during refactoring, silently capturing an outer `this` rather than throwing an error that would alert you to architectural drift. Function declarations fail fast with explicit errors when `this` is accessed incorrectly.

## Practical Code Examples from the React Source

The React codebase demonstrates both patterns in production test suites and internal fixtures.

### Function Declaration Style

This pattern appears in [`packages/react/src/__tests__/ReactStrictMode-test.internal.js`](https://github.com/facebook/react/blob/main/packages/react/src/__tests__/ReactStrictMode-test.internal.js) at line 32, demonstrating the classic hoisted approach:

```javascript
// src/components/Greeting.js
function Greeting({name}) {
  return <p>Hello, {name}!</p>;
}
export default Greeting;

```

### Const Arrow Function Style

Modern ES-6 syntax appears in [`packages/react/src/__tests__/ReactProfiler-test.internal.js`](https://github.com/facebook/react/blob/main/packages/react/src/__tests__/ReactProfiler-test.internal.js) at line 614, showing the expression-based approach:

```javascript
// src/components/Farewell.js
export const Farewell = ({name}) => <p>Good‑bye, {name}.</p>;

```

Both components participate identically in the React profiler and strict mode tests, confirming runtime parity despite syntactic divergence.

## Summary

- React renders function declarations and const arrow components identically, with no measurable performance difference between the two styles.
- Function declarations support hoisting, enabling flexible file organization and circular dependencies that would break with const expressions.
- Function declarations provide a cleaner migration path to class components if legacy lifecycle methods become necessary.
- Arrow functions capture lexical `this`, which provides no benefit in React function components and may mask programming errors.
- Choose function declarations for top-level exported components and arrow functions for tightly scoped inline utilities, maintaining consistency with surrounding code in the `facebook/react` repository.

## Frequently Asked Questions

### Is there a performance difference between const and function components?

No measurable runtime difference exists between the two declaration styles. The JavaScript engine treats both as ordinary function objects, and React’s reconciler does not distinguish between them during the diffing or commit phases. Any performance impact from syntax choice is purely theoretical and negligible in production applications.

### Why does my const component throw "not defined" when my function component works?

Const declarations are not hoisted, meaning the identifier does not exist until the assignment statement executes. If you reference a const component above its definition—such as in a default export or early return statement—you encounter a temporal dead zone error. Function declarations are hoisted to the top of their containing scope, making them available throughout the entire module regardless of declaration position.

### Which style does the React core team prefer?

The `facebook/react` repository uses both styles interchangeably based on context. Function declarations dominate in test files and formal component modules, while arrow functions appear frequently in fixtures and inline utility components. The team prioritizes consistency within a given file over repository-wide uniformity, choosing the syntax that best fits the specific use case and surrounding code patterns.

### Can I mix both styles in the same project?

Yes. Mixing function declarations for primary components and const arrows for inline utilities is a common and valid pattern. The key is maintaining **local consistency**—if a file predominantly uses `const` for other assignments, using a const arrow function for components preserves visual rhythm. Conversely, files emphasizing traditional JavaScript patterns benefit from function declarations throughout.