Перейти к содержанию
Mercury
Русский
Дизайн книга
Меню
Русский

Reflect.7. Следим за временем жизни

За время жизни компонента значение может измениться много раз. Хуки Reflect сохраняют свойства этого времени жизни, а не подписываются на каждое последующее значение.

Reflect 4.1.1 · Интерактивное упражнение

Открыть упражнение на всю страницу

Определите наблюдаемое время жизни

hooks.mounted вызывается после монтирования. hooks.unmounted — при завершении соответствующего времени жизни. Каждый хук может быть функцией, событием или эффектом; вызов привязан к области. Оба получают итоговые свойства, сохранённые для этого времени жизни.

import {createElement as h} from "@fiberfx/hyperscript";
import {event, store} from "@fiberfx/hypergraph";
import {reflect} from "@fiberfx/reflect";

const changed = event<string>();
const recorded = event<string>();
export const $name = store("Ada").on(changed, (_, name) => name);
export const $history = store<string[]>([])
  .on(recorded, (history, entry) => [...history, entry]);
export const Lifetime = reflect({
  view: (p: {name: string}) => h("p", null, p.name),
  bind: {name: $name},
  hooks: {
    mounted: props => recorded(`mounted: ${props.name}`),
    unmounted: props => recorded(`unmounted: ${props.name}`),
  },
});

Владелец решает, выводить ли Lifetime, например через visible ? h(Lifetime, {}) : null. Историю $history читайте в отдельном представлении через общий слой привязки. Оба представления должны находиться под нужным Provider.

Обычное обновление свойства не начинает новое время жизни хуков. Замена области завершает прежнее и начинает следующее. Перестановка строки с прежним ключом его не завершает. Хуки variant принадлежат обёртке, поэтому сама смена ветви их не перезапускает.

Смонтируйте, обновите и удалите

Откройте эксперимент со временем жизни. Оставьте имя Ada и нажмите Смонтировать. Не скрывая представление, замените имя на Grace. Затем нажмите Размонтировать.

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

Сравните текущее и сохранённое

Смонтированное представление должно обновиться до Grace. В истории должны появиться монтирование: Ada, затем размонтирование: Ada. Обновление свойства не должно добавлять ещё одну запись монтирования.

Снова смонтируйте представление, пока в поле Grace. Новое время жизни должно сохранить Grace. История позволяет проследить порядок событий, но не доказывает автоматическое освобождение всех ресурсов приложения. В настоящем тесте фиксируйте и проверяйте конкретный ресурс, которым владеете.

Откажитесь от неверного ожидания

Ожидание «unmounted получает последнее отображённое имя» неверно для этих хуков. Нельзя освобождать ресурс по новому имени, если он был создан с другим сохранённым ключом. Свяжите создание и освобождение с одной идентичностью времени жизни. Реакции на изменение значения разместите в модели или в компонентном хуке с соответствующей зависимостью.

Возвращённая из hooks.mounted функция очистки не относится к API Reflect: возвращаемое значение игнорируется. Если подходит этот контракт, используйте отдельный unmounted. Дескрипторов ресурсов, автоматического учёта функций освобождения и нового языка жизненного цикла в 4.1.1 нет.

Начните новое наблюдение

Нажмите Начать упражнение заново и повторите Ada → монтирование → Grace → размонтирование. Перезапуск удаляет сцену вместе со сбросом значений модели; само удаление может добавить запись очистки. Читайте итоговую историю, а не предполагайте, что сброс означает отсутствие очистки.

В тесте сначала размонтируйте компонент, проверьте очистку и лишь затем удалите историю или освободите область. Обратный порядок может скрыть результат очистки или заставить её обращаться к уже освобождённой области.

Проверьте серверную границу

При серверном рендеринге читаются значения области, но не вызываются ни mounted, ни unmounted. Выведите то же представление с двумя областями запросов и разными именами, сравните HTML и проверьте, что история хуков пуста. Это отдельные проверки изоляции вывода и отсутствия хуков.

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

Назад · Курс · Далее