Задать вопрос
@ShamanR

Как правильно реализовать компонент на React?

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

Представим что я делаю компонент dropdown. У него есть выпадающее меню.
Бест практис - делать глупый компонент, который занимается только рендерингом по пропсам, с этим проблем нет, написал так что показ/скрытие выпадашки зависит от пропса. А вот далее проблема - надо управлять состоянием показа меню, значит делаем обёртку в виде умного компонента, внутри которого есть метод-колбек, который дергается при клике на тайтл дропдауна и меняет стейт. В итоге получается такой себе standalone дропдаун, который можно подключать куда угодно и он даже реализован по канонам.

Далее я подумал о том, а что если мы захотим при инициализации дропдаун сразу открыть, так что надо сделать компонент одновременно и управляемым и нет - наткнулся на "uncontrollable" пакет, подключил, стало ещё более круто - можно юзать либо стендалон компонент, который сам следит за своим состоянием, либо если надо управлять из того место где мы его подключаем, мы передаём через пропсы управляющие данные и рулим дропдауном "сверху".

Тут то можно было и закончить, но довольно часто требуются такие юзкейсы: Дропдаун висит где-то в одной части страницы, а кнопка управления дропдауном в другой её части, и единственное что у них общего - это рут-элемент в паре прыжков "наверх" от каждого из них. При этом дропдаун должен быть uncontrollable, т.е. хранить в себе свой стейт и независимо переключать показ своего меню, НО, при клике на вышеобозначенную кнопку он должен, например, раскрыться, независимо от своего состояния (рскрыт/скрыт).

И как это реализовать я не понимаю. если делать контроллируемый компонент извне, то придётся писать логику, а это значит что другие компоненты будут о нём много знать. Из того с чем я работал, я бы мог предложить две реализации подобного:
  • У дропдаун компонента делается публичное апи с методами show() и hide(), и через пропсы принимается колбек, в который отдаётся объект с апи.
  • реакт-way, используется Ref, через который дергается нужный метод. Минус этого подхода - через реф отдаётся вся подноготная компонента с потрохами, да и использование рефов в таком контексте мне кажется очень бэд практис


Интуиция мне подсказывает что есть какое-то очень простое решение.
Знаю что подобное могло бы решиться редаксом, но я хотел бы узнать как это написать на более-менее чистом реакте, и хочется чтобы это решение было именно стендалон, т.е. чтобы можно было взять этот компонент и добавить в другой проект, в котором может не оказаться MobX или Redux. Опять же, интересно такое решение которое в более менее крупной компании на код ревью не завернут со словами "да у вас же костыль", хочется энтерпрайзное, то что вы каждый день пишете на работе.
Если есть какие-то статьи на подобную тему, буду очень рад ссылкам.
  • Вопрос задан
  • 215 просмотров
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 1
alexiusp
@alexiusp
senior frontend developer
Я бы рекомендовал использовать редакс. Совсем не обязательно сам компонент делать зависимым от редакса. Нужный пропс из состояния может считывать его непосредственный предок.
Если идти без редакса, то придётся, видимо, прокидывать нужный пропс до общего предка. Оба варианта с пробрасыванием методов слишком усложняют проблему, как мне кажется.
Либо сделать какой-то универсальный класс-сервис (так сказать angular-way), который будет хранить состояние этого дропдауна и предоставлять API к нему. Вообще же этот юзкейс довольно специфичный и, если вы хотите создать переиспользуемый компонент, то всё что вам нужно у вас уже есть - можно на этом остановиться. Все эти хитрые варианты использования - проблемы того, кто будет пользоваться компонентом, а не разработчика компонента.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы