Автор оригинала: Yurii Rashkovskii.
В этой короткой части я хочу показать вам нетрадиционную, но удивительно производительный способ организовать проекты React/Redux (и другие потоки). Для тех, кто не сможет прочитать до конца, вы можете найти реализацию этого подхода в моем стеке React/Redux, Реагировать .
Многие приложения React/Redux принимают следующую планировку каталога (или изменение его):
src/ actions/ UserActions.js FooActions.js constants/ UserConstants.js FooConstants.js reducers/ UserReducers.js FooReducers.js components/ Login.js Dashboard.js
Будь то, сделано, следуя другим примерам, или здравый смысл, я не уверен. Но я нахожу этот макет, чтобы быть очень контрпродуктивным. Навигация по моим приложениям было кошмаром (тонны импорта, константы перекрестных ссылок и т. Д.), Все, пытаясь оставаться сосредоточенными на задаче под рукой.
Вышеуказанная макет незначительно лучше, чем организация каталогов или пакетов по типам сущности. Подумайте об этом в Java:
com.foo.bar. classes interfaces singletons factories
Это делает для вас много смысла? Это говорит вам что-нибудь о том, что делает приложение, или как отфильтровать ресурсы, связанные с доменом, на котором вы работаете? (На самом деле, рельсы видят эту ошибку, разоблачали приложение/{модели, контроллеры, представления}
Я предлагаю организацию приложений Redux бизнес-доменами. Что-то вроде этого:
src/ user/ index.js orders/ index.js messages/ index.js
Таким образом, во время работы над одним доменом вам не нужно слишком запрыгивать через иерархию проекта, и вы можете легко переименовать весь домен, без необходимости переименовать 4-5 файлов!
Мысль о бизнес-доменах привел меня к другой реализации. Что если мы попытаемся использовать некоторые кусочки DDD ( Дизайн домена ), чтобы подтвердить типы данных по состояниям и действиям?
Представьте себе, что состояние определено так:
const State = t.struct({ currentUser: t.maybe(User) }, 'UserState')
Вы можете сделать это с TComb !
И имея акцию создателя, определенного аналогично:
const doSomething = t.struct({ type: t.refinement(t.String, (s) => s == "doSomething", "action") payload: t.Integer }, "doSomething")
Теперь, в вашем редукторе, вы можете на самом деле можно использовать подходящие возможности в вашем редукторе!
t.match(action, doSomething, (action) => { ... })
Обратите внимание, как мы избавились от утомительного постоянного определения/шага импорта?
Теперь, конечно, некоторые проблемы, связанные с использованием TCOMB. Например, значения TComb не являются простыми объектами, поэтому Redux отказывается принимать их. Но это может быть довольно легко решить, разработав функцию промежуточного программного обеспечения Redux.
Недавно я провел некоторое время, работая над стеком React/Redux, который обращается к этому и другим вопросам. Это называется Реагировать Отказ Самое главное, в отличие от других решений «RACT RACT BOTERPLATE», реагируют – это библиотека, и вам не нужно клонировать и следовать, чтобы иметь возможность включать последние изменения. Это все еще довольно грубо по краям, находясь в нескольких днях, но я приглашаю вас попробовать. Проверьте это!