Область видимости переменных в компонентах

Riot.js строится на компонентной архитектуре, где каждый компонент представляет собой независимую единицу интерфейса с собственной логикой, шаблоном и состоянием. Понимание областей видимости переменных в компонентах критично для корректного управления состоянием и реактивностью.

Локальные переменные компонента

Внутри компонента можно объявлять переменные с помощью let, const или var. Эти переменные существуют только в контексте функции, которая инициализирует компонент. Пример:

import { component } from 'riot';

component('example-component', () => {
  let count = 0;

  function increment() {
    count++;
    console.log(count);
  }

  return { increment };
});
  • count доступна только внутри функции компонента.
  • Она недоступна напрямую в других компонентах.
  • Локальные переменные не влияют на реактивность шаблона, если их не возвращать из функции компонента.

Свойства компонента (state)

Состояние компонента определяется через возвращаемый объект:

return { count };

Если переменная включена в объект, возвращаемый из компонента, Riot автоматически связывает её с шаблоном. Пример:

<counter>
  <button oncl ick={increment}>Increment</button>
  <p>{count}</p>

  <script>
    import { component } from 'riot';

    component('counter', () => {
      let count = 0;

      function increment() {
        count++;
      }

      return { count, increment };
    });
  </script>
</counter>
  • Ключевой момент: любые изменения count автоматически обновляют DOM, если переменная возвращена из компонента.

Внешние переменные и контекст

Переменные, объявленные за пределами компонента, могут использоваться внутри, но они не становятся реактивными:

let globalCount = 0;

component('counter-global', () => {
  function increment() {
    globalCount++;
    console.log(globalCount);
  }

  return { increment };
});
  • globalCount увеличивается, но DOM не обновляется автоматически.
  • Для реактивности глобальные значения нужно связывать с локальными переменными или использовать события для уведомления компонента.

Область видимости функций

Функции внутри компонента имеют доступ ко всем локальным переменным и возвращаемым свойствам:

component('example', () => {
  let message = 'Hello';

  function updateMessage(newMessage) {
    message = newMessage;
  }

  return { message, updateMessage };
});
  • updateMessage может изменять message.
  • Изменение message в функции обновит DOM только если переменная возвращена.

Вложенные компоненты и слоты

Вложенные компоненты имеют собственную область видимости. Локальные переменные родителя недоступны напрямую. Связь между компонентами осуществляется через props и события:

<parent>
  <child msg={parentMessage}></child>

  <script>
    import { component } from 'riot';

    component('parent', () => {
      let parentMessage = 'Text from parent';
      return { parentMessage };
    });

    component('child', ({ msg }) => {
      console.log(msg); // доступ к переданному значению
    });
  </script>
</parent>
  • msg передается как параметр. Изменения локальных переменных родителя не отражаются автоматически в дочернем компоненте без повторной передачи значения.

Замыкания и реактивность

Использование замыканий позволяет создавать приватные состояния:

component('counter-closure', () => {
  let count = 0;

  function increment() {
    count++;
    update(); // обновление DOM через метод компонента
  }

  function update() {
    console.log(`Count: ${count}`);
  }

  return { increment };
});
  • Замыкания обеспечивают инкапсуляцию состояния.
  • Прямой доступ из шаблона возможен только через возвращаемые свойства.

Итоговые рекомендации по области видимости

  1. Локальные переменные – приватны, не влияют на шаблон.
  2. Возвращаемые свойства – реактивны и связываются с DOM.
  3. Глобальные переменные – используются осторожно, без реактивности.
  4. Функции – имеют доступ к локальному состоянию, могут изменять возвращаемые свойства.
  5. Вложенные компоненты – общаются через props и события, внутренние переменные из родителя недоступны напрямую.

Правильное понимание области видимости обеспечивает чистоту архитектуры компонентов и предсказуемость реактивного поведения в приложениях на Riot.js.