Notion clone application developed by a third year university team using React.js, Redux, Firebase and Firestore.
# установка yarn
npm install -g yarn
# проверка версии
yarn --version
# добавление библиотек
yarn add <package> [--dev]
# установка всех зависимостей
yarn
# or
yarn install
Ссылка для документации yarn: https://yarnpkg.com/getting-started/usage
# запуск приложения
yarn start
# запуск тестов
yarn test
# build проекта в build/
yarn build
# если хотим достать webpack конфигурации и как-то поменять, не советую, если нужно лучше
# добавить к проекту модуль craco
yarn eject
# проверка линтером eslint
yarn lint
# форматирование кода по установленным правилам с помощью prettier
yarn format
Полезная ссылка для доп. настройки create-react-app: https://create-react-app.dev/docs/getting-started
В папке project_layout хранится верстка проекта
-
assets - храним .css
-
components - здесь храним "dumb" компоненты, которые отвечают только за отображение props компонента, а также какие-то локальные функции которые не меняют props или state, по факту основная верстка компонента
-
containers - здесь компоненты отвечают за получение, взаимодействие c данными из store во время первоначального и последующего рендера, также в зависимости от полученных данных в return определяем какой "dumb" component и с какими props отрендерится
для получения данных/состояний из store изпользуем useSelector(), если хотим поменять данные из store используем useDispatch()
для первоначального рендера, а также перендера компонента можно использовать useEffect(), только не забываем указывать зависимости у данного хука
ЖЕЛАТЕЛЬНО придерживаться подхода containers/ "dumb" components
- constants - здесь храним нединамические крупные состояния проекта, которые на вряд ли поменяются на протяжении всего проекта но если все-таки поменяются то поменяем мы их в одном месте Пример: url-ы проекта, максимальная глубина вложенности noteList
- firebase - инициализация firebase, при росте кол-ва файлов конфигурации их можно будет перенсти в отдельную папку
- pages - основные глобальные компоненты - страницы сайта, здесь можно добавить глобальную логику из store, по типу проверки на наличие авторизации, или каких-то данных которые обязаны быть при загрузке страницы и без которых дальнейшая логика страницы будет бесмысленна. Чаще всего здесь просто предзагружаем данные но какого-то изменения с данными не ведем, максимум убираем активное состояние глобального preloader
- services - прописываем взаимодейстие, обработку данных на уровне запросов в бд, у нас все на основе realtime firebase
- static - фотографии, видео, svg - встретили svg, создаем файл, копируем в него svg тело, на месте пропуска , не забываем импортировать как ReactComponent import {ReactComponent as Primer} from '../../static/svg/primer.svg'
- store/actions - dispatch функции, которые мы вызваем в containers/pages когда хотим предзагрузить данные или изменить данные из store, все что в них происходит - доставание данных из бд посредством обращения к уже написанным методам в services. Далее передаем их в dispatch функции, которые отправляют их на уровень reducers(прим. смотри reducers), Также здесь мы можем дополнительно предобрабатывать данные при необходимости
- store/reducers - здесь начальные состояния данных, а также вывод измененных состояний при совершении actions, благодяря types которые описаны в начале каждого файла actions.js мы определаяем какие данные выводятся. Здесь также можно дополнительно возиться с данными, конкатинировать их с уже существующими данными, фильтровать, или просто выводить и т.д. ВАЖНО все новые reducer добавляем в файл rootReducers.js, здесь собираются все состояния
- store/selectors - чаще всего reducer имеет сложную структуру состояний: {notes,user, loading, rest}, здесь мы это структуру превращаем в простую: notes=state.notes; user=state.user, это нужно, чтобы в containers при получении состояний из useSelector(), мы получали конкретные состояния, а не работали с огромным объектом из кучи разных состояний, помимо этого здесь можно выводить вспомогательные состояния по типу countNotes=all(state.notes).count и т.п.
- utils - дополнителные функции, при работе с данными могут получатся одинаковые функции, или могут выйти огроменные функции со сложной логикой (прим. часто связано с оптимизацией или просто преобразованием структур данных, например полученные данные из бд часто плоские и не соотвествуют логике отображения в компонентах) а файлик actions, or reducers,все-таки хочется сделать компактным красивым,чтоб сразу понятно что происходит а тут 200 строк c логикой данных а не dispatch функции хочется сразу закрыть и больше не открывать, поэтому сложную, повторяющуюся логику лучше вынести в utils
При работе над проектом мы старались придерживаться принципов написания хорошего кода, но нам еще многому предстоит научиться. Тут несколько статей и конечно же всеми любимые документации.
- hooks react - https://reactdev.ru/handbook/hooks-reference/
- store (selectors) - https://habr.com/ru/post/564004/
- firebase realtime database 9 версия - https://firebase.google.com/docs/database/web/start?hl=nl
- state, reducers, actions - https://redux.js.org/tutorials/fundamentals/part-3-state-actions-reducers