Перейти к содержанию

React вызывает компоненты и хуки

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

Никогда не вызывайте функции компонентов напрямую

Компоненты должны использоваться только в JSX. Не вызывайте их как обычные функции. Их должен вызывать React.

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

1
2
3
4
5
6
7
function BlogPost() {
    return (
        <Layout>
            <Article />
        </Layout>
    ); // ✅ Good: Only use components in JSX
}

1
2
3
function BlogPost() {
    return <Layout>{Article()}</Layout>; // 🔴 Bad: Never call them directly
}

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

Позволяя React оркестровать рендеринг, вы также получаете ряд преимуществ:

  • Компоненты становятся больше чем функциями. React может дополнить их такими возможностями, как локальное состояние с помощью хуков, которые привязаны к идентификатору компонента в дереве.
  • Типы компонентов участвуют в согласовании. Позволяя React вызывать ваши компоненты, вы также сообщаете ему больше о концептуальной структуре вашего дерева. Например, когда вы переходите от рендеринга <Feed> к странице <Profile>, React не будет пытаться использовать их повторно.
  • React может улучшить пользовательский опыт. Например, он может позволить браузеру выполнять некоторую работу между вызовами компонентов, чтобы повторный рендеринг большого дерева компонентов не блокировал основной поток.
  • Лучшая история отладки. Если компоненты являются гражданами первого класса, о которых знает библиотека, мы можем создать богатые инструменты разработчика для интроспекции в процессе разработки.
  • Более эффективное согласование. React может точно определить, какие компоненты в дереве нуждаются в повторном рендеринге, и пропустить те, которые не нуждаются. Это делает ваше приложение более быстрым и шустрым.

Никогда не передавайте хуки как обычные значения

Хуки должны вызываться только внутри компонентов или хуков. Никогда не передавайте их как обычные значения.

Хуки позволяют дополнить компонент функциями React. Они всегда должны вызываться как функция и никогда не передаваться как обычное значение. Это позволяет использовать локальные рассуждения, или возможность для разработчиков понять все, что может делать компонент, рассматривая его в отдельности.

Нарушение этого правила приведет к тому, что React не будет автоматически оптимизировать ваш компонент.

Не мутируйте динамически хуки

Хуки должны быть как можно более «статичными». Это означает, что их не следует динамически изменять. Например, это означает, что вы не должны писать хуки более высокого порядка:

1
2
3
4
5
function ChatInput() {
    // 🔴 Bad: don't write higher order Hooks
    const useDataWithLogging = withLogging(useData);
    const data = useDataWithLogging();
}

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

1
2
3
4
5
6
7
8
function ChatInput() {
    // ✅ Good: Create a new version of the Hook
    const data = useDataWithLogging();
}

function useDataWithLogging() {
    // ... Create a new version of the Hook and inline the logic here
}

Не используйте хуки динамически

Хуки также не следует использовать динамически: например, вместо инъекции зависимостей в компоненте передавать хук в качестве значения:

1
2
3
4
function ChatInput() {
    // 🔴 Bad: don't pass Hooks as props
    return <Button useData={useDataWithLogging} />;
}

You should always inline the call of the Hook into that component and handle any logic in there.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
function ChatInput() {
    return <Button />;
}

function Button() {
    const data = useDataWithLogging(); // ✅ Good: Use the Hook directly
}

function useDataWithLogging() {
    // If there's any conditional logic to change the Hook's behavior,
    // it should be inlined into the Hook
}

Таким образом, <Button /> гораздо проще понять и отладить. Когда хуки используются динамически, это значительно увеличивает сложность вашего приложения и препятствует локальному мышлению, делая вашу команду менее продуктивной в долгосрочной перспективе. Кроме того, так легче случайно нарушить Правила использования хуков, согласно которым хуки не должны вызываться условно. Если вы столкнулись с необходимостью издеваться над компонентами для тестов, лучше вместо этого издеваться над сервером, чтобы он отвечал консервированными данными. Если есть возможность, обычно эффективнее тестировать приложение с помощью сквозных тестов.

Источник — https://react.dev/reference/rules/react-calls-components-and-hooks

Комментарии