Я храню ссылку в моем хранилище redux и использую mapStateToProps, чтобы предоставить ссылку для компонентов, которым нужен доступ к ней.
Сохраненная ссылка выглядит так:
ref={node => this.myRefToBePutInReduxGlobalStore = node}
Каков правильный propType для этой ссылки?
ref
prop, является функцией с первым аргументом, ссылкой на элемент DOM или null. Это функция .propType
дляrefs
, но можете использовать дляprops
. Поскольку вы передаете его в магазин redux, он представляется какprop
подобныйthis.props.myRefToBePutInReduxGlobalStore
.myRefToBePutInReduxGlobalStore
должен быть типом узла, поэтомуPropTypes.node
должен работать на васPropType.object
потому что ref - это в основном экземпляр класса, который является объектом. Следовательно, когда вы передаете элемент ref в качестве реквизита, он будет иметь тип объектаОтветы:
TL; DR
Если вы хотите указать ссылку, которая ожидает только нативные элементы DOM, такие как a
div
или aninput
, правильное определение будет следующим: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) }) ])
Ответ на конкретную проблему, описанную в исходном сообщении
В примере с вопросом OP необходимо объявить не тип ref prop, а материал, на который указывает ссылка, который будет передан из redux using
mapStateToProps
. Тип свойства для элемента DOM будет:myRefToBePutInReduxGlobalStore: PropTypes.instanceOf(Element)
(если это элемент DOM). Хотя я бы:myElementToBePutInReduxGlobalStore
(элемент не является ссылкой)Длинный ответ на актуальный вопрос
В: Каков правильный proptype для ссылки в 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(props) { const inputRef = React.useRef() useLayoutEffect(function focusWhenStuffChange() { inputRef.current?.focus() }, [props.stuff]) return <FancyInput inputRef={inputRef} /> }
Сегодня в React существует два вида ссылок:
{ current: [something] }
обычно создаетсяReact.createRef()
помощником илиReact.useRef()
хуком[something]
качестве аргумента (как в примере OP)Примечание: исторически вы также могли использовать строку ref, но она считается устаревшей и будет удалена из реакции
Второй элемент достаточно прост и требует следующего типа пропеллера:
PropTypes.func
.Первый вариант менее очевиден, потому что вы можете указать тип элемента, на который указывает ссылка.
Много хороших ответов
ref
может указывать на что-то еще, кроме элемента DOM.Если вы хотите быть полностью гибким:
refProp: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.any }) ])
Вышеупомянутое просто обеспечивает форму объекта ref w /
current
property. Он будет работать в любое время для любого реф. Для использования типа опоры, который является способом выявить любые несоответствия при разработке , этого, вероятно, будет достаточно. Кажется очень маловероятным, что объект с формой{ 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 }) ])
Примечание: указанный выше тип опоры интересен, потому что он также охватывает компоненты реакции и собственные элементы DOM, потому что все они наследуют базовый javascript.
Object
Не существует единственного хорошего способа объявить тип опоры для ссылки, это зависит от использования. Если ваш реф указывает на что-то очень узнаваемое, возможно, стоит добавить конкретный тип опоры. В противном случае кажется, что достаточно просто проверить общую форму.
Примечание о рендеринге на стороне сервера
Если ваш код должен запускаться на сервере, если вы еще не заполняете среду DOM,
Element
или любой другой тип на стороне клиента будетundefined
в NodeJS. Вы можете использовать следующую прокладку для поддержки:Element = typeof Element === 'undefined' ? function(){} : Element
Следующие страницы React Docs дают больше информации о том, как использовать ссылки, как объектные, так и обратные вызовы , а также как использовать
useRef
ловушку.Ответ обновлен благодаря @Rahul Sagore, @Ferenk Kamra, @svnm и @Kamuela Franco
источник
Element
не определено на рендеринге на стороне сервера. Любое решение для этого?Element = typeof Element === 'undefined' ? function(){} : Element
(предложено Райаном Флоренсом в каком-то выпуске на github). Если это сработает для вас, я могу добавить это к своему ответу.if (!isBrowser) { global.Element = null; }
. Работал у меня.isBrowser = typeof window !== 'undefined';
Очень похоже на сообщение @Pandaiolo,
PropTypes.elementType
теперь добавленforwardedRef: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.elementType }) ]),
При использовании PropTypes> = 15.7.0
PropTypes.elementType
был добавлен 10 февраля 2019 года в этот PRисточник
elementType
не сработало для меня, поэтому я фактически протестировал кучу типов опор на различных типах компонентов, на которые может указывать ссылка, в песочнице. Вот результаты: codesandbox.io/s/loving-benz-w6fbh . Я не уверен, что рассмотрел все возможности, но кажется, что правильный тип свойства для элемента DOM -instanceOf(Element)
(илиobject
), для класса -instanceOf(Component)
(илиobject
), а для конкретного варианта использования функционального компонента, которыйuseImperativeHandle
его используетobject
. Мысли?Я проверяю только предпочтительный способ, и поскольку PropType.object не очень ценен, я в конечном итоге использовал это:
PropTypes.shape({ current: PropTypes.instanceOf(Element) })
источник
Я проверил все вышеперечисленные ответы, но получил предупреждение от реакции, поэтому много исследовал и получил правильный ответ.
import React, { Component } from 'react'; ComponentName.propTypes = { reference: PropTypes.oneOfType([ PropTypes.func, PropTypes.shape({ current: PropTypes.instanceOf(Component) }), ]), };
источник