Это руководство содержит в себе наиболее разумный подход к написанию JavaScript и ReactJS (JSX) кода.
- Компонент не должен содержать в себе состояний.
- Компоненты делятся на два типа:
- Presentation component — презентационный компонент. Главная роль — отображение переданных данных от контейнера.
- Container — контейнер. Главная роль — хранение функциональной части и логики компонента. Передаёт итоговые данные в презентационный компонент.
В презентационном компоненте не желательно хранить логику или любую другую функциональную часть. Исключение — компонент-класс.
- Не создавать компонент-класс, если нет определённой необходимости.
- Используйте библиотеку
lodash
для работы с объектами и массивами. Безопасный метод_.get
предотвратит ошибки при работе с объектами.
- Всегда указывайте явные
defaultProps
для всех свойств, которые не указаны как необходимые.
Почему? propTypes является способом документации, а предоставление defaultProps позволяет читателю вашего кода избежать множества неясностей. Кроме того, это может означать, что ваш код может пропустить определенные проверки типов. Пример верного и неверного решения: https://gist.github.com/Archakov06/45fe1264dca019d48a0c32c49a56d356
// ✅ GOOD
<Button onClick={removeItem.bind(this, id)}>Удалить</Button>
// ❌ BAD
<Button
onClick={() => {
removeItem(id);
}}>
Удалить
</Button>
Старайтесь не создавать анонимную функции, для передачи данных в другую функцию. Для подобной ситуации, используйте метод — .bind().
Метод bind() создаёт новую функцию, которая при вызове устанавливает в качестве контекста выполнения this предоставленное значение. В метод также передаётся набор аргументов, которые будут установлены перед переданными в привязанную функцию аргументами при её вызове.
В onClick
передавайте функцию removeItem
с привязкой контекст и новых аргументов.
Подробнее о .bind()
: https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
// ✅ GOOD
<Input onChange={this.props.onChange} />
// ✅ GOOD
<Input onChange={this.props.onChange.bind(this, 'myField')} />
// ❌ BAD
<Input onChange={value => this.props.onChange(value)} />
В данном случае, метод onChange
автоматически передаст value
первым аргументом в функцию this.props.onChange
.
Если же вы хотите добавить дополнительные аргументы, после value
, пробрасывайте их через .bind(this, ...)
. В итоге, onChange
получит 2 значания — введённое значение пользователем и строку myField
.
// ✅ GOOD
const mapDispatchToProps = dispatch => bindActionCreators(appActions, dispatch);
// ✅ GOOD
import { action1, action2, action3 } from 'src/actions/appActions';
const mapDispatchToProps = {
action1,
action2,
action3
};
// ✅ GOOD
connect(mapStateToProps, appActions);
// ❌ BAD
const mapDispatchToProps = dispatch => ({
...bindActionCreators(appActions, dispatch)
});
Вы можете передать в connect()
вторым аргументом объект, содержащий в себе все ваши экшены. Не обязательно передавать функцию вторым аргументом.
// ✅ GOOD
if (a > b) {
calculate(a, b);
}
// ❌ BAD
if (a > b) calculate(a, b);
Подробнее: https://goo.gl/iNhtc7
Список полезных материалов и некоторых источников, откуда я брал правила написанию кода на ReactJS и JavaScript.
Ресурсы (ReactJS):
- https://github.com/leonidlebedev/javascript-airbnb/blob/master/react/README.md
- https://habr.com/post/309422/ — Паттерны React (перевод на русский). (EN: https://reactpatterns.com/).
- https://habr.com/company/ruvds/blog/349198/ — Шаблоны проектирования в React
- https://medium.com/@tronin/%D0%BF%D0%B0%D1%82%D1%82%D0%B5%D1%80%D0%BD%D1%8B-react-%D0%BA%D0%BE%D0%BC%D0%BF%D0%BE%D0%BD%D0%B5%D0%BD%D1%82%D0%BE%D0%B2-53cb7f0765df — Паттерны React компонентов
- https://gist.github.com/datchley/4e0d05c526d532d1b05bf9b48b174faf — React/Redux Style Guide (EN)
- https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md#protip
Ресурсы (JavaScript):