Переход от традиционной трехфайловой структуры приложения HTML/CSS/JS к использованию фреймворка/библиотеки, такой как React, пугает и, по крайней мере, немного сбивает с толку. Скорее всего, вас научили множеству правил о том, как держать логику отдельно от контента, отдельно от стиля. Теперь, когда вы начали с React, вы, вероятно, помещаете onClick непосредственно в свой JSX, запускаете карту внутри своего метода рендеринга, чтобы вернуть ряд элементов ‹li›, и используете условный рендеринг, чтобы определить, не отображать конкретный JSX.

Иными словами, старые боги мертвы, и новые боги, стремящиеся вытеснить их, не требуют такой же строгой приверженности принципам. Следовательно, понимание того, как подходить к размещению вашей логики и вашего контента в React, может быть рискованным и чреватым опасностью. Итак, я хотел бы изложить несколько вещей, которые мне хотелось бы лучше понять о React, когда я начал с ним, для тех из нас, кто с головой ныряет в его теплые и манящие объятия.

React предназначен в первую очередь для отображения пользовательского интерфейса и управления им.

Теперь, когда шлюзы открыты и у вас есть карт-бланш, чтобы сделать ваши компоненты универсальным магазином для всего, что вам нужно сделать в этом компоненте, я хотел бы воспользоваться моментом, чтобы подумать, что вам не нужно делать это, что приближается Таким образом, ваши компоненты не обязательно являются лучшей идеей, потому что это может сделать ваши компоненты раздутыми и сложными для тестирования.

Например, допустим, вы работаете с большим набором данных, который хотите разбить на части и отобразить на странице, но данные не отформатированы таким образом, чтобы их можно было легко разбить на легко отображаемый контент. Вы можете сделать это внутри самого компонента, который будет рендерить контент, но потенциально это может добавить десятки, если не сотни строк кода в файл, основной обязанностью которого будет просто рендеринг контента и обработка событий.

Таким образом, вместо того, чтобы запускать функции очистки данных внутри вашего файла компонента, было бы разумно вместо этого создать файл утилиты, чтобы сделать это вместо этого, и импортировать связанные функции, которые вам нужны, из этого файла в ваш компонент. Это позволяет вашим компонентам быть компактными и сфокусированными на рендеринге контента и обработке событий в DOM, при этом поддерживая концепцию единой ответственности. Чем больше вы сможете сфокусировать свои методы компонентов на простой установке состояния или вызове внешних функций, которые передаются как реквизиты или импортируются из служебных файлов, тем легче будет читать и понимать ваш код в будущем.

setState() работает странно

Первое, что вам нужно понять о setState(), это то, что он асинхронный. Например, давайте возьмем этот небольшой фрагмент кода:

Если вы когда-либо запускали блок кода, подобный этому, а затем видели ложный вывод на консоль, это вполне нормально и может затруднить использование преимуществ изменения состояния. Для надлежащего изучения асинхронного JavaScript и того, как работает цикл обработки событий, я настоятельно рекомендую выступление Филиппа Робертса на эту тему.

Следствием этого является то, что вам нужно либо организовать свой код с учетом того факта, что setState() не всегда происходит сразу после его вызова, либо воспользоваться тем фактом, что setState() может принимать функцию обратного вызова в качестве второго аргумента:

Использование подобных обратных вызовов в setState() гарантирует, что console.log не будет вызываться до тех пор, пока не будет выполнено setState().

Всегда думайте о тестировании

Тестирование внешнего интерфейса, как известно, сложно и утомительно, и React не является исключением. Когда вы пишете свой код, всегда помните об этом.

Например, если вы используете API выборки для выполнения запроса GET, часто рекомендуется использовать какую-либо анимацию или метку, чтобы указать пользователю, что приложение ожидает возврата данных. Часто это делается через государство. Однако вы также хотите удалить эту метку после завершения вызова выборки. Это потенциально может привести к многократному вызову setState в одном методе.

Хотя этот код должен выполняться нормально, проверить, как он вызывает setState(), будет сложно, поскольку this.state.loading всегда будет оцениваться как false. Если вы хотите проверить, установлено ли для загрузки значение true, вам нужно разбить этот вызов setState() на другую функцию, которая вызывается перед выборкой.

Выделив изменение загрузки в состоянии, вы можете просто проверить, вызывается ли setLoading() функцией getData(), а затем проверить изменение состояния на setLoading().

Как упоминалось ранее, метод setState() довольно странный, и привыкание к работе с ним как с асинхронным, так и с довольно частым вызовом может усложнить задачу.