Skip to content

Commit

Permalink
hooks-custom: various improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
lex111 authored and another-guy committed Feb 28, 2019
1 parent a0e71e8 commit 470c690
Showing 1 changed file with 20 additions and 20 deletions.
40 changes: 20 additions & 20 deletions content/docs/hooks-custom.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ prev: hooks-rules.html

*Хуки* -- новинка в React 16.8, которая позволяет использовать состояние и другие возможности React без написания классов.

Создание пользовательских хуков позволяет вам перенести компонентную логику в функции, которые можно многократно использовать.
Создание пользовательских хуков позволяет вам перенести логику компонентов в функции, которые можно повторно использовать.

В разделе [использование хука эффекта](/docs/hooks-effect.html#example-using-hooks-1) мы увидели компонент из приложения чата, в котором отображается сообщение о том, находится ли наш друг в сети:

Expand All @@ -30,13 +30,13 @@ function FriendStatus(props) {
});
if (isOnline === null) {
return 'Loading...';
return 'Загрузка...';
}
return isOnline ? 'Online' : 'Offline';
return isOnline ? 'В сети' : 'Не в сети';
}
```

Теперь предположим, что в приложении чата также есть список контактов, и мы хотим отображать зелёным цветом имена онлайн пользователей. Мы могли бы просто скопировать и вставить приведённую выше логику в наш компонент `FriendListItem`, но это не самый лучший вариант:
Теперь предположим, что в приложении чата также есть список контактов, и мы хотим отображать зелёным цветом имена пользователей, которые сейчас в сети. Мы могли бы просто скопировать и вставить приведённую выше логику в наш компонент `FriendListItem`, но это не самый лучший вариант:

```js{4-15}
import React, { useState, useEffect } from 'react';
Expand All @@ -63,15 +63,15 @@ function FriendListItem(props) {
}
```

Вместо этого мы разделим эту логику между `FriendStatus` и `FriendListItem`.
Вместо этого, мы бы хотели, чтобы `FriendStatus` и `FriendListItem` разделяли эту логику.

Традиционно в React у нас было два популярных способа обмена логикой состояния между компонентами: [рендер-пропсы](/docs/render-props.html) и [компоненты высшего порядка](/docs/higher-order-components.html). Рассмотрим, как хуки решают многие из тех же задач, не заставляя вас добавлять больше компонентов в дерево.
Когда одинаковую логику состояния нужно повторно использовать в нескольких компонентах, в React традиционно применялись [рендер-пропсы](/docs/render-props.html) и [компоненты высшего порядка](/docs/higher-order-components.html). Рассмотрим, как хуки решают многие из тех же задач, не добавляя лишних компонентов в ваше дерево.

## Извлечение логики в пользовательский хук {#extracting-a-custom-hook}

Когда мы хотим разделить логику между двумя JavaScript-функциями, мы извлекаем её в третью функцию. Так как компонент и хук являются функциями, то для них это тоже работает!
Когда мы хотим, чтобы две JavaScript-функциии разделяли какую-то логику, мы извлекаем её в третью функцию. И компоненты и хуки являются функциями, поэтому с ними это тоже работает!

**Пользовательский хук -- это функция JavaScript, имя которой начинается с "`use`", и которая может вызывать другие хуки.** Например, функция `useFriendStatus` ниже -- это наш первый пользовательский хук:
**Пользовательский хук -- это JavaScript-функция, имя которой начинается с "`use`", и которая может вызывать другие хуки.** Например, функция `useFriendStatus` ниже -- это наш первый пользовательский хук:

```js{3}
import React, { useState, useEffect } from 'react';
Expand All @@ -96,7 +96,7 @@ function useFriendStatus(friendID) {

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

В отличие от React-компонента, пользовательский хук не обязательно должен иметь конкретную сигнатуру. Мы можем решить, что он принимает в качестве аргументов, и должен ли он что-либо возвращать. Другими словами, это как обычная функция. Её имя всегда следует начинать с `use`, чтобы вы могли сразу увидеть, что к ней применяются [правила хуков](/docs/hooks-rules.html).
В отличие от React-компонента, пользовательский хук не обязательно должен иметь конкретную сигнатуру. Мы можем решить, что он принимает в качестве аргументов, и должен ли он что-либо возвращать. Другими словами, всё как в обычных функциях. Её имя всегда следует начинать с `use`, чтобы вы могли сразу увидеть, что к ней применяются [правила хуков](/docs/hooks-rules.html).

Цель нашего хука `useFriendStatus` -- подписать нас на статус друга. Поэтому он принимает в качестве аргумента `friendID` и возвращает статус друга в сети:

Expand All @@ -123,9 +123,9 @@ function FriendStatus(props) {
const isOnline = useFriendStatus(props.friend.id);
if (isOnline === null) {
return 'Loading...';
return 'Загрузка...';
}
return isOnline ? 'Online' : 'Offline';
return isOnline ? 'В сети' : 'Не в сети';
}
```

Expand Down Expand Up @@ -153,13 +153,13 @@ function FriendListItem(props) {

Поскольку хуки являются функциями, мы можем передавать информацию между ними.

Продемонстрируем это используя другой компонент из нашего гипотетического примера чата. Это средство выбора получателей сообщений чата, которое показывает, находится ли выбранный в данный момент друг в сети:
Продемонстрируем это, используя другой компонент из нашего гипотетического примера чата. Это средство выбора получателей сообщений чата, которое показывает, находится ли выбранный в данный момент друг в сети:

```js{8-9,13}
const friendList = [
{ id: 1, name: 'Phoebe' },
{ id: 2, name: 'Rachel' },
{ id: 3, name: 'Ross' },
{ id: 1, name: 'Татьяна' },
{ id: 2, name: 'Алла' },
{ id: 3, name: 'Лиля' },
];
function ChatRecipientPicker() {
Expand Down Expand Up @@ -197,11 +197,11 @@ function ChatRecipientPicker() {

## `используйтеВоображение()` {#useyourimagination}

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

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

Например, у вас есть сложный компонент, который содержит множество внутренних состояний, которые управляются специальным образом. `useState` не помогает объединить логику обновления, поэтому вы можете написать её как [Redux](https://redux.js.org/)-редюсер:
Например, у вас есть сложный компонент, содержащий множество внутренних состояний, каждое из которых управляется особым образом. `useState` не упрощает централизацию логики обновления, поэтому её можно попробовать переписать как [Redux](https://redux.js.org/)-редюсер:

```js
function todosReducer(state, action) {
Expand All @@ -218,7 +218,7 @@ function todosReducer(state, action) {
}
```

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

Что если мы могли бы написать хук `useReducer`, который позволяет нам управлять *внутренним* состоянием нашего компонента с помощью редюсера? Упрощённая версия может выглядеть так:

Expand Down Expand Up @@ -249,4 +249,4 @@ function Todos() {
}
```

Так как необходимость управления внутренним состоянием с помощью редюсера в сложном компоненте достаточно распространена, мы встроили хук `useReducer` прямо в React. Вы найдёте его вместе с другими встроенными хуками в [справочнике API хуков](/docs/hooks-reference.html).
Так как необходимость управления внутренним состоянием с помощью редюсера в сложном компоненте достаточно распространена, мы встроили хук `useReducer` прямо в React. Вы найдёте его вместе с другими встроенными хуками в [API-справочнике хуков](/docs/hooks-reference.html).

0 comments on commit 470c690

Please sign in to comment.