Ответ 1
Ответьте на конкретный вопрос, описанный в оригинальном сообщении
В примере с вопросом о OP, необходимо объявить не тип опоры ref, а материал, на который указывает ссылка, и который будет передан из Redx с использованием mapStateToProps
. Тип поддержки для элемента DOM будет: myRefToBePutInReduxGlobalStore: PropTypes.instanceOf(Element)
(если это элемент DOM). Хотя я бы:
- Переименуйте статику в
myElementToBePutInReduxGlobalStore
(это не ссылка как таковая) - Избегайте хранения несериализуемых данных в хранилище с избыточностью
- Избегайте передачи элементов в подпорки, как объяснил инженер React Себ Маркбедж
Ответ на актуальный вопрос
В: Какой правильный тип для ссылки в React?
Пример использования:
function FancyInput({ inputRef }) {
return (
<div className="fancy">
Fancy input
<input ref={inputRef} />
</div>
)
}
FancyInput.propTypes = {
inputRef: ??? // What is the correct prop type here?
}
function App() {
const inputRef = React.useRef()
useEffect(function focusWhenStuffChange() => {
inputRef.current && inputRef.current.focus()
}, [stuff])
return <FancyInput inputRef={inputRef} />
}
Сегодня в реакции существуют два вида ссылок:
- Объект, который выглядит так:
{ current: [something] }
, обычно создаетсяReact.createRef()
вспомогательный илиReact.useRef()
хук - Функция обратного вызова, которая получит
[something]
в качестве аргумента (как в примере с OP)
Примечание: исторически вы также могли использовать строку ref, но она считалась устаревшей и будет удалена из реакции
Второй элемент довольно прост и требует следующего типа пропеллера: PropTypes.func
.
Первый вариант менее очевиден, поскольку вы можете указать тип элемента, на который указывает ссылка.
TL; DR
Если вы ожидаете только собственные элементы DOM, такие как div
или input
, правильное определение будет следующим:
refProp: PropTypes.oneOfType([
// Either a function
PropTypes.func,
// Or the instance of a DOM native element (see the note about SSR)
PropTypes.shape({ current: PropTypes.instanceOf(Element) })
])
Длинный ответ
ref
может указывать на что-то еще, кроме элемента DOM.
Если вы хотите быть полностью гибким:
refProp: PropTypes.oneOfType([
PropTypes.func,
PropTypes.shape({ current: PropTypes.any })
])
Вышеприведенное только что применяет форму объекта ref со свойством current
. Это будет работать в любое время для любого вида реф. Для цели использования типа проп, который является способом выявления любых несоответствий при разработке, этого, вероятно, достаточно. Кажется очень маловероятным, что объект с формой { current: [any] }
и переданный в refToForward
опору, не будет действительным ссылочным номером.
Тем не менее, вы можете объявить, что ваш компонент не ожидает какого-либо реф, а только определенного типа, учитывая, для чего он нужен.
Я установил песочницу, демонстрирующую несколько различных способов объявления ссылки, даже несколько нестандартных, и затем тестирую их со многими типами проп. Вы можете найти его здесь.
Если вы ожидаете только ссылку, указывающую на собственный элемент ввода, а не на какой-либо HTML Element
:
refProp: PropTypes.oneOfType([
PropTypes.func,
PropTypes.shape({ current: PropTypes.instanceOf(HTMLInputElement) })
])
Если вы ожидаете только ссылку, указывающую на компонент класса React:
refProp: PropTypes.oneOfType([
PropTypes.func,
PropTypes.shape({ current: PropTypes.instanceOf(Component) })
])
Если вы ожидаете, что ссылка, указывающая на функциональный компонент с помощью useImperativeHandle
, предоставит какой-то открытый метод:
refProp: PropTypes.oneOfType([
PropTypes.func,
PropTypes.shape({ current: PropTypes.object })
])
Примечание: приведенный выше тип prop интересен тем, что он также охватывает компоненты реакции и собственные элементы DOM, поскольку все они наследуют базовый JavaScript Object
Не существует единственного хорошего способа объявить тип реквизита для ссылки, это зависит от использования. Если ваш реф указывает на что-то очень идентифицированное, возможно, стоит добавить определенный тип проп. В противном случае достаточно просто проверить общую форму.
Примечание о рендеринге на стороне сервера
Если ваш код должен выполняться на сервере, если вы уже не заполняете DOM-среду, Element
или любой другой тип клиентской стороны будет undefined
в NodeJS. Вы можете использовать следующую прокладку для его поддержки:
Element = typeof Element === 'undefined' ? function(){} : Element
На следующих страницах React Docs содержится более подробное описание того, как использовать ссылки, объектные и обратные вызовы, а также как использовать ловушку useRef
Ответ обновлен благодаря @Rahul Sagore, @Ferenk Kamras и @svnm