Организация компонентов в React проекте

habralogo.jpg
Многие проекты руководствуются рекомендациями Presentational and Container Components, но уважаемый автор признаётся в сносках, что концепция разделения спорная, и компоненты можно смешивать. А если это так, то зачем тащить чемодан без ручки? Все компоненты проекта удобнее хранить в одной общей папке. Какие плюсы:
  • Простота навигации по файловой системе.
  • Уникальные имена компонентов проекта.
  • Импорт без боли ('…/…/…/…/…/…').

Когда проект вырастет, следует дробить его на приватные npm-пакеты, инкапсулируя реализацию. Но не выращивать дерево подпапок внутри папки компонентов — развивать и поддерживать такое ощутимо сложнее. Проверено.

Все компоненты организованы по доменному принципу в одной папке src/componens. Например, можно определить домены: Post — отображение публикации, PostForm — форма редактирования публикации.


Как создать доменный компонент — src/components/Post/Post.js.


Почему нельзя использовать index.js вместо Post.js — соблюдается уникальность имен файлов компонентов внутри проекта, так упрощается навигация по вкладкам редактора (и в WebStorm будет работать ценная функция «Find Usages» для контекстного меню выделенного файла — см. примечание).


Все компоненты в папке доменного компонента получают префикс доменного компонента (Post*.js).


Подпапки в папке доменного компонента не допускаются, внутри плоская структура файлов из компонентов-потомков (PostTitle.js, PostBody.js) и компонентов-предков (PostViewPage.js, PostListPage.js). Компоненты-потомки используются внутри доменного компонента, а компоненты-предки используются снаружи (в роутере).


Чтобы инкапсулировать импорт доменных компонентов, следует задать внутри каждой папки доменного компонента свой package.json, в котором прописать точку входа «main»:


{
  "name": "Post",
  "version": "0.0.0",
  "private": true,
  "main": "./Post.js",
}

Кроме того, внутри файла доменного компонента (Post.js) объявлен реэкспорт компонентов-предков:


import PostViewPage from './PostViewPage'
import PostListPage from './PostListPage'
//...
export { PostViewPage, PostListPage }
export default Post

К сожалению, нельзя использовать конструкцию «export from» (ограничение WebStorm), например:


export { default as PostViewPage } from './PostViewPage'

В результате не требуется явного доступа к файлам внутри папки компонентов, например:


import Post from 'components/Post/Post'

По соглашению, разрешается использовать импорт только по доменному имени компонента:


import Post, { PostViewPage, PostListPage } from 'components/Post'

Исходники


Примечание по функции «Find Usages» в WebStorm. Как минимум, есть три контекста использования: 1) по выделенному файлу, 2) по выделенной переменной или символу, 3) по выделенному слову default в экспорте компонента.


1) Выделим файл components/Post/PostViewPage.js, результат поиска:


// Post.js
import PostViewPage from './PostViewPage'

2) Выделим символ PostViewPage внутри файла PostViewPage.js, результат поиска:


// PostViewPage.js
PostViewPage.propTypes = {}

3) Выделим default в экспорте компонента PostViewPage, результат поиска:


// routes.js
import { PostViewPage } from 'components/Post'

Как видно, третий способ использования выдает наиболее полезную информацию для компонента-предка.


PS Найден правильный способ прикрутить Styled-JSX для Create React App. Теперь CSS-блоки живут внутри файлов компонентов естественным для себя образом — в CSS-формате (против инлайн-стилей JS-объектов). И не нужно беспокоиться за глобальную область видимости.

Комментарии (0)

© Habrahabr.ru