В общих чертах петтерн "observer" (обозреватель, наблюдатель) предполагает, что есть некий объект, который меняет своё состояние и оповещает об этом тех, кто подписан на уведомления (subscribers). Применительно к React'у это более, чем актуально, поскольку при изменении состояния (данных), компоненты должны перерисовываться, а значит, должны следить за изменениями сообветствующих данных.
При этом компоненты, которые себя перерисовывают, получают данные, зависят от них, но state, который хранит состояние, не должен зависеть от них - то есть он не должен сам вызывать метод перерисовки, находящийся в компонентах. Тогда как компоненты узнают, что state изменился?
А вот как:
С одной стороны, файл, где происходит отрисовка компонентов (допустим, index.js) вызывает rerender() и передает туда state, который предварительно импортирует:
rerender(state);
То есть index.js зависит от state'а, как и положено.
Но index.js также вызывает метод subscribe и передает туда вызов свой rerender():
subscribe(rerender);
Теперь rerender() может быть вызван прямо в state, при этом state от него не зависит, а только использует реализацию.
С другой стороны, при изменении state вызывает callSubscriber(), но его реализацию он получает в распоряжение из метода subscribe():
// некоторые изменения данных
callSubscriber();
В самом state он описывается приблизительно так:
export const subscribe = (observer) => {
rerender = observer;
}
То есть теперь callSubscriber(), вызываемый в state, - это тот самый rerender(), который реализован в index.js.
Следовательно, теперь при любом изменениии state, он вызывает метод перерисовки, который он получил через subscribе. Это означает, что state по-преженему не зависит от UI, потому что ему всё равно, как реализована перерисовка - он её только вызывает, но не импортирует.
P.S.: Обычно паттерн "observer" объясняют на примере Java. В некотором смысле оно понятнее, потому что там есть интерфейсы как отдельные сущности. Но вот мне помогло объяснение в исполнении Димыча.
Комментариев нет:
Отправить комментарий