Как я могу указать, что проп принимается с ссылкой в пользовательском компоненте React?

Вопрос или проблема

У меня есть пользовательский компонент в 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 и другими аналогичными случаями.

Оцените материал
Добавить комментарий

Капча загружается...