Перейти к содержанию

compilationMode

Параметр compilationMode управляет тем, как React Compiler выбирает функции для компиляции.

1
2
3
{
  compilationMode: 'infer' // or 'annotation', 'syntax', 'all'
}

Описание

compilationMode

Управляет стратегией, по которой React Compiler определяет, какие функции оптимизировать.

Тип

1
'infer' | 'syntax' | 'annotation' | 'all'

Значение по умолчанию

'infer'

Варианты

  • 'infer' (по умолчанию): Компилятор использует интеллектуальные эвристики, чтобы определить компоненты и хуки React:
  • Функции, явно помеченные директивой "use memo"
  • Функции, названные как компоненты (PascalCase) или хуки (префикс use), которые при этом создают JSX и/или вызывают другие хуки

  • 'annotation': Компилируются только функции, явно помеченные директивой "use memo". Подходит для постепенного внедрения.

  • 'syntax': Компилируются только компоненты и хуки, которые используют синтаксис Flow component и hook.

  • 'all': Компилируются все функции верхнего уровня. Не рекомендуется, потому что могут быть скомпилированы функции, не относящиеся к React.

Предупреждения

  • Режим 'infer' требует, чтобы функции следовали соглашениям об именовании React, иначе они не будут обнаружены
  • Режим 'all' может ухудшить производительность, компилируя служебные функции
  • Режим 'syntax' требует Flow и не работает с TypeScript
  • Независимо от режима, функции с директивой "use no memo" всегда пропускаются

Использование

Режим вывода по умолчанию

Режим 'infer' по умолчанию хорошо подходит для большинства кодовых баз, которые следуют соглашениям React:

1
2
3
{
  compilationMode: 'infer'
}

В этом режиме будут скомпилированы такие функции:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// ✅ Compiled: Named like a component + returns JSX
function Button(props) {
  return <button>{props.label}</button>;
}

// ✅ Compiled: Named like a hook + calls hooks
function useCounter() {
  const [count, setCount] = useState(0);
  return [count, setCount];
}

// ✅ Compiled: Explicit directive
function expensiveCalculation(data) {
  "use memo";
  return data.reduce(/* ... */);
}

// ❌ Not compiled: Not a component/hook pattern
function calculateTotal(items) {
  return items.reduce((a, b) => a + b, 0);
}

Постепенное внедрение в режиме annotation

Для постепенной миграции используйте режим 'annotation', чтобы компилировать только помеченные функции:

1
2
3
{
  compilationMode: 'annotation'
}

Затем явно пометьте функции, которые нужно скомпилировать:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// Only this function will be compiled
function ExpensiveList(props) {
  "use memo";
  return (
    <ul>
      {props.items.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}

// This won't be compiled without the directive
function NormalComponent(props) {
  return <div>{props.content}</div>;
}

Использование режима синтаксиса Flow

Если кодовая база использует Flow вместо TypeScript:

1
2
3
{
  compilationMode: 'syntax'
}

Затем используйте синтаксис компонентов Flow:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// Compiled: Flow component syntax
component Button(label: string) {
  return <button>{label}</button>;
}

// Compiled: Flow hook syntax
hook useCounter(initial: number) {
  const [count, setCount] = useState(initial);
  return [count, setCount];
}

// Not compiled: Regular function syntax
function helper(data) {
  return process(data);
}

Исключение отдельных функций

Независимо от режима компиляции, используйте "use no memo", чтобы пропустить компиляцию:

1
2
3
4
5
6
7
8
function ComponentWithSideEffects() {
  "use no memo"; // Prevent compilation

  // This component has side effects that shouldn't be memoized
  logToAnalytics('component_rendered');

  return <div>Content</div>;
}

Устранение неполадок

Компонент не компилируется в режиме infer

В режиме 'infer' убедитесь, что компонент следует соглашениям React:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// ❌ Won't be compiled: lowercase name
function button(props) {
  return <button>{props.label}</button>;
}

// ✅ Will be compiled: PascalCase name
function Button(props) {
  return <button>{props.label}</button>;
}

// ❌ Won't be compiled: doesn't create JSX or call hooks
function useData() {
  return window.localStorage.getItem('data');
}

// ✅ Will be compiled: calls a hook
function useData() {
  const [data] = useState(() => window.localStorage.getItem('data'));
  return data;
}

Источник — https://react.dev/reference/react-compiler/compilationMode

Комментарии