🦉 Объект Context 🦉

Содержание

Введение

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

С помощь объекта Context, каждый компонент может быть подписан (с помощью хука useContext) на его состояние, будет обновляться каждый раз, когда изменяется состояние контекста.

Пример

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

const deviceContext = new Context({ isMobile: true });
App.env.deviceContext = deviceContext;

Если мы хотим сделать его полностью отзывчивым, нам нужно обновлять его значение всякий раз, когда обновляется размер экрана:

const isMobile = () => window.innerWidth <= 768;
window.addEventListener(
  "resize",
  owl.utils.debounce(() => {
    const state = deviceContext.state;
    if (state.isMobile !== isMobile()) {
      state.isMobile = !state.isMobile;
    }
  }, 15)
);

Затем, каждый компонент, который хотим подписать и рендерить по разному в зависимости от того в мобильном ли мы режиме или настольном.

class SomeComponent extends Component {
  static template = xml`
    <div>
      <t t-if=device.isMobile>
          some simplified user interface
      </t>
      <t t-else="">
          a more advanced user interface
      </t>
    </div>`;
  device = useContext(this.env.deviceContext);
}

Описание элементов

Context

Объект Context должен создаватьс с помощью объекта состояния:

const someContext = new Context({ some: "key" });

Теперь его состояние доступно по ключу state:

someContext.state.some = "other key";

Именно так глобальный код (например, адаптивный код выше) должен читать и обновлять состояние контекста. Однако компоненты никогда не должны считывать состояние контекста непосредственно из контекста, вместо этого они должны использовать хук useContext для правильной регистрации изменений состояния.

Обратите внимание, что хук Context отличается от версии React. Например, нет понятия поставщик/потребитель. Таким образом, функция Context сама по себе не позволяет использовать другое состояние контекста в зависимости от места компонента в дереве компонентов. Однако эту функциональность можно получить, при необходимости, с использованием дочерней среды.

useContext

Хук useContext это нормальный способ для компонента для самостоятельного отслеживания изменений состояний контексат. Метод useContext возвращает состояние контекста:

device = useContext(this.env.deviceContext);

Это просто наблюдаемое состояние (с помощью Owl Observer), которое содержит общую информацию.