- Вопрос или проблема
- Ответ или решение
- Как указать, что пропс принимает ref в пользовательском компоненте React
- Шаг 1. Импортируйте forwardRef
- Шаг 2. Объявите компонент с использованием forwardRef
- Шаг 3. Измените PropTypes
- Шаг 4. Установите значения по умолчанию
- Шаг 5. Экспортируйте компонент
- Полный код
- Заключение
Вопрос или проблема
У меня есть пользовательский компонент в React, который я хотел бы иметь возможность принимать ref (т.е. он должен иметь ref
в качестве одного из своих свойств). (Это необходимо, если мы хотим использовать его в качестве дочернего компонента ToolTip
.) Мы используем Material-UI для наших компонентов и PropTypes для проверки свойств, а наш код написан на JavaScript. Код компонента схож со следующим:
import { FormControlLabel, Switch } from '@mui/material'
import PropTypes from 'prop-types'
function LabeledSwitch({ label, checked, onChange, required, ...otherProps }) {
return (
<FormControlLabel
control={<Switch {...otherProps} />}
label={label}
checked={checked}
onChange={onChange}
required={required}
/>
)
}
LabeledSwitch.propTypes = {
label: PropTypes.string.isRequired,
checked: PropTypes.bool,
onChange: PropTypes.func,
required: PropTypes.bool
}
LabeledSwitch.defaultProps = {
checked: false,
onChange: null,
required: false
}
export default LabeledSwitch
Я хочу добавить ref
в список свойств компонента, при этом свойство control у FormControlLabel
должно быть установлено на:
control={<Switch {...otherProps} inputRef={ref} />}
а значение по умолчанию для ref
должно быть null
. Моя проблема в том, что я не могу просто добавить
ref: PropTypes.ref,
в список LabeledSwitch.propTypes
, так как ref
не является типом, который распознает PropTypes. Как мне указать, что свойство ref
на самом деле является ref? Или мне просто указать, что это element
(что, по моему мнению, не звучит правильно)?
Ответ или решение
Как указать, что пропс принимает ref в пользовательском компоненте React
Чтобы передать ref
в свой пользовательский компонент React, вы можете использовать механизм forwardRef
. Это позволяет вашему компоненту принимать ref
как пропс и передавать его дальше на дочерний компонент. Давайте разберём, как это сделать в вашем случае.
Шаг 1. Импортируйте forwardRef
Вам нужно импортировать forwardRef
из React, чтобы создать компонент, который поддерживает рефы.
import React, { forwardRef } from 'react';
import { FormControlLabel, Switch } from '@mui/material';
import PropTypes from 'prop-types';
Шаг 2. Объявите компонент с использованием forwardRef
Измените ваш компонент LabeledSwitch
, чтобы он использовал forwardRef
. Это позволит вашему компоненту принимать ref
как второй аргумент функции.
const LabeledSwitch = forwardRef(function LabeledSwitch(
{ label, checked, onChange, required, ...otherProps },
ref
) {
return (
<FormControlLabel
control={<Switch {...otherProps} inputRef={ref} />}
label={label}
checked={checked}
onChange={onChange}
required={required}
/>
);
});
Шаг 3. Измените PropTypes
Так как ref
не является типом, который поддерживается PropTypes, вы не можете указать его в PropTypes. Вместо этого достаточно просто не добавлять его в propTypes
.
LabeledSwitch.propTypes = {
label: PropTypes.string.isRequired,
checked: PropTypes.bool,
onChange: PropTypes.func,
required: PropTypes.bool,
};
Шаг 4. Установите значения по умолчанию
Если вам это необходимо, вы можете установить значения по умолчанию для остальных пропсов, но значения по умолчанию для ref
обычно не указываются, так как он передается извне.
LabeledSwitch.defaultProps = {
checked: false,
onChange: null,
required: false,
};
Шаг 5. Экспортируйте компонент
Теперь экспортируйте компонент как обычно.
export default LabeledSwitch;
Полный код
В итоге ваш компонент будет выглядеть следующим образом:
import React, { forwardRef } from 'react';
import { FormControlLabel, Switch } from '@mui/material';
import PropTypes from 'prop-types';
const LabeledSwitch = forwardRef(function LabeledSwitch(
{ label, checked, onChange, required, ...otherProps },
ref
) {
return (
<FormControlLabel
control={<Switch {...otherProps} inputRef={ref} />}
label={label}
checked={checked}
onChange={onChange}
required={required}
/>
);
});
LabeledSwitch.propTypes = {
label: PropTypes.string.isRequired,
checked: PropTypes.bool,
onChange: PropTypes.func,
required: PropTypes.bool,
};
LabeledSwitch.defaultProps = {
checked: false,
onChange: null,
required: false,
};
export default LabeledSwitch;
Заключение
Используя forwardRef
, вы можете легко передавать рефы в собственные компоненты React, что особенно полезно при работе с UI-библиотеками, такими как Material-UI. Надеюсь, это поможет вам успешно модифицировать ваш компонент для использования с ToolTip
и другими аналогичными случаями.