Настоятельно рекомендую иметь готовый сниппет для начала работы над новым компонентом. Разделение вашего проекта на более мелкие компоненты сделает ваш код более удобным для чтения и сопровождения. Наличие готового сниппета поможет вам в этом, облегчив запуск нового компонента.
Мой рабочий процесс создания нового компонента выглядит следующим образом:
- Создайте новую директорию с файлом index.js
- Разверните сниппет в index.js
- Создайте файл styles.module.css
Совет: В PHPStorm вы можете ввести путь, например, ‘FancyBox/index.js’ в диалоговом окне «Новый файл», и он создаст и папку, и файл.
📦 Project root
┗ 📂src
┗ 📂components
┗ 📂FancyBox
┣ 📜index.js
┗ 📜styles.module.css
Мой фрагмент содержит следующий код для минимального компонента React:
Импорт React
import React from 'react'
Это необходимо для того, чтобы иметь возможность писать jsx.
concatClassNames
import { concatClassNames as cn } from '../../helpers.js'
Это особенно полезно, когда в компонент добавляются условные классы, поэтому я всегда импортирую его. Подробнее об этом вы можете узнать здесь.
styles.module.css
import * as styles from './styles.module.css'
Я использую модули CSS во всех своих проектах, и большинство моих компонентов имеют стили.
Я перестал использовать import styles from './styles.module.css'
, потому что Gatsby сделал импорт CSS модулей как ES модулей по умолчанию.
Единственный минус в том, что это пока не работает с react-scripts@5, так как, похоже, есть проблемы с этим (однако это работает с react-scripts@4 и есть обходные пути для v5).
Если у вас есть идея, как опубликовать компонент, чтобы он мог использоваться как проектом, загружающим CSS модули как ES модули, так и CommonJS, вы можете помочь мне здесь
Именованный экспорт для компонента
export function FancyBox(props) {
Создание именованного экспорта для компонента имеет некоторые преимущества перед экспортом по умолчанию. Например, вы можете экспортировать подкомпоненты, такие как элементы списка, из одного и того же места. Мой главный компонент всегда называется точно так же, как папка компонента.
Вместе с именованием основного файла компонента index.js
это выглядит потрясающе при импорте:
import { List, ListItem } from '../components/List'
Есть небольшое предостережение относительно именования всех ваших файлов компонентов «index.js»: Имя файла ничего не говорит о компоненте. Поэтому, когда вы открываете файл в редакторе, на вкладке может быть написано ‘index.js’, что немного двусмысленно. Для меня это не является большой проблемой, потому что мой редактор добавляет имя папки, когда два открытых файла имеют одинаковое имя.
Разрушение реквизита
const {
className,
children,
...containerProps
} = props;
Первое, что я делаю в реальном компоненте, это разрушаю реквизит. containerProps
будет содержать ВСЕ оставшиеся реквизиты, которые не были явно деструктурированы выше этой строки. Таким образом, если вы используете этот компонент следующим образом:
<FancyBox onClick={handleClick} id={'this-is-unique'} />
Отрисованный div будет иметь обработчик клика и html id. Это очень полезно, поскольку вы можете использовать компонент react как html-элемент без дополнительного кода. Лично я влюбился в этот метод, но вы должны знать о рисках.
Использование разбросанного синтаксиса для реквизитов позволяет легко передать недопустимые HTML-атрибуты в DOM или нежелательные реквизиты другим компонентам. React Docs
Одно правило, которое помогает предотвратить это — никогда не использовать props.something
в коде вашего компонента, а всегда добавлять реквизит, который вы собираетесь использовать, в список destructure.
По крайней мере, для меня это принесло больше радости и комфорта, чем проблем.
Для некоторых компонентов я отказываюсь от этого.
JSX по умолчанию
return <div className={cn(className, styles.fancyBox)} {...containerProps}>
{children}
</div>;
Сначала className из props конкатенируется с className из таблицы стилей CSS модулей. Затем применяются containerProps и, наконец, дочерний реквизит передается div явным образом.
Конечно, я меняю html-элемент на тот, который лучше всего подходит для моего компонента, например, a для кнопки и так далее.
Полный фрагмент
import React from 'react'
import { concatClassNames as cn } from '../../helpers.js'
import * as styles from './styles.module.css'
export function FancyBox(props) {
const {
className,
children,
...containerProps
} = props;
return <div className={cn(className, styles.fancyBox)} {...containerProps}>
{children}
</div>;
}
Несколько советов для IDE от Jetbrains, таких как PHPStorm
В IDE Jetbrains можно считывать имя папки и использовать его при именовании имен классов и функций. Это позволяет получить сниппет, который автоматически применяет правильные имена.
Мои переменные в Живом шаблоне следующие:
NAMEPASCAL
Выражение: пусто
Значение по умолчанию: groovyScript("String[] p=_editor.getVirtualFile().getPath().split('/');String prevLast = p[p.length-2];")
.
Пропустить, если определено: false
NAMECAMEL
Выражение: пусто
Значение по умолчанию: camelCase(NAMEPASCAL)
Пропустить, если определено: true
import React from 'react'
import { concatClassNames as cn } from '../../helpers.js'
import * as styles from './styles.module.css'
export function $NAMEPASCAL$(props) {
const {
className,
children,
...containerProps
} = props;
return <div className={cn(className, styles.$NAMECAMEL$)} {...containerProps}>
{children}
$END$
</div>;
}
Что помогает вам запускать новые компоненты? Дайте мне знать, что вы думаете.