useImperativeHandle¶
useImperativeHandle
- это хук React, который позволяет вам настроить хэндл-обработчик, отображаемый как ссылка.
1 |
|
Описание¶
useImperativeHandle(ref, createHandle, dependencies?)
¶
Вызовите useImperativeHandle
на верхнем уровне вашего компонента, чтобы настроить экспортируемый им ref handle:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Параметры¶
ref
:ref
, полученный в качестве второго аргумента от функции рендерингаforwardRef
.createHandle
: Функция, которая не принимает аргументов и возвращает хэндл ссылки, которую вы хотите раскрыть. Этот ref handle может иметь любой тип. Обычно вы возвращаете объект с методами, которые вы хотите раскрыть.- опционально
dependencies
: Список всех реактивных значений, на которые ссылается кодcreateHandle
. Реактивные значения включают пропсы, состояние, а также все переменные и функции, объявленные непосредственно в теле вашего компонента. Если ваш линтер настроен на React, он проверит, что каждое реактивное значение правильно указано в качестве зависимости. Список зависимостей должен иметь постоянное количество элементов и быть написан inline по типу[dep1, dep2, dep3]
. React будет сравнивать каждую зависимость с предыдущим значением, используя сравнениеObject.is
. Если в результате повторного рендеринга изменилась какая-то зависимость, или если вы опустили этот аргумент, ваша функцияcreateHandle
будет повторно выполнена, и вновь созданный хэндл будет назначен ссылке.
Возвращает¶
Хук useImperativeHandle
возвращает undefined
.
Использование¶
Выставление пользовательской функции ref для родительского компонента¶
По умолчанию компоненты не открывают свои DOM-узлы родительским компонентам. Например, если вы хотите, чтобы родительский компонент MyInput
имел доступ к DOM-узлу <input>
, вы должны выбрать forwardRef
:
1 2 3 4 5 |
|
С помощью приведенного выше кода ссылка на MyInput
получит DOM-узел <input>
Однако вместо этого вы можете выставить пользовательское значение. Чтобы настроить пользовательский дескриптор, вызовите useImperativeHandle
на верхнем уровне вашего компонента:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Обратите внимание, что в приведенном выше коде ref
больше не пересылается на input
.
Например, предположим, что вы не хотите раскрывать весь DOM-узел input
, но хотите раскрыть два его метода: focus
и scrollIntoView
. Для этого сохраните реальный DOM браузера в отдельном реферере. Затем используйте useImperativeHandle
, чтобы раскрыть дескриптор только с теми методами, которые вы хотите, чтобы вызывал родительский компонент:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Теперь, если родительский компонент получит ссылку на MyInput
, он сможет вызвать для него методы focus
и scrollIntoView
. Однако у него не будет полного доступа к лежащему в основе DOM-узлу input
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
Выставление собственных императивных методов¶
Методы, которые вы раскрываете через императивный дескриптор, не обязательно должны точно соответствовать методам DOM. Например, этот компонент Post
раскрывает метод scrollAndFocusAddComment
через императивный хэндл. Это позволяет родительской Page
прокручивать список комментариев и фокусировать поле ввода, когда вы нажимаете на кнопку:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Не злоупотребляйте рефами
Рефы следует использовать только для императивного поведения, которое вы не можете выразить как пропс: например, прокрутка к узлу, фокусировка узла, запуск анимации, выделение текста и так далее.
Если вы можете выразить что-то как пропс, вы не должны использовать реф. Например, вместо того, чтобы раскрывать императивный дескриптор типа { open, close }
из компонента Modal
, лучше взять isOpen
как пропс, например <Modal isOpen={isOpen} />
. Effects может помочь вам раскрыть императивное поведение через пропсы.
Источник — https://react.dev/reference/react/useImperativeHandle