Использование forwardRef с проптипами и eslint - PullRequest
6 голосов
/ 13 января 2020

Я пытаюсь использовать forwardRef для Button в проекте, используя eslint и prop-types .

Это то, что я пробовал до сих пор, и ошибки, которые я получаю каждый раз:

Первая попытка

function Button ({ action = { callback: () => {}, title: 'unknown' } }, ref) {
  return (<button ref={ref} onClick={action.callback} title={action.description} type="button">{action.icon || action.title}</button>)
}

Button.propTypes = {
  action: Action.isRequired
}

export default forwardRef(Button)

Это выдаст мне следующее предупреждение в консоли: Warning: forwardRef render functions do not support propTypes or defaultProps. Did you accidentally pass a React component?

Вторая попытка

function ButtonFunction ({ action = { callback: () => {}, title: 'unknown' } }, ref) {
  return (<button ref={ref} onClick={action.callback} title={action.description} type="button">{action.icon || action.title}</button>)
}

const Button = forwardRef(ButtonFunction);

Button.propTypes = {
  action: Action.isRequired
}

export default ButtonFunction;

Я получаю: action is missing in props validation.

Третья попытка

const Button = forwardRef(({ action = { callback: () => {}, title: 'unknown' } }, ref) => {
  return (<button ref={ref} onClick={action.callback} title={action.description} type="button">{action.icon || action.title}</button>)
});

Button.propTypes = {
  action: Action.isRequired
}

export default Button;

На этот раз я получаю: Component definition is missing display name.

Итак, каков правильный путь сделать это?

1 Ответ

10 голосов
/ 17 января 2020

Вы почти закончили с третьей попыткой. Но вам не нужно использовать дважды forwardRef, достаточно первого использования с объявлением Button. Правило отображаемого имени - это не ошибка (ни на JavaScript, ни на уровне React), а скорее преднамеренная опора, чтобы показать «реальное» имя компонента, используемого React в сообщениях отладки. В вашем случае функция forwardRef скроет «реальное» имя компонента для транспилятора.

Вы даже можете отключить это правило, если реальная проблема - написать displayName для каждого из этих случаев.

https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/display-name.md

const Button = forwardRef(({ action = { callback: () => {}, title: 'unknown' } }, ref) => {
  return (<button ref={ref} onClick={action.callback} title={action.description} type="button">{action.icon || action.title}</button>)
});

Button.propTypes = {
  action: Action.isRequired
}

Button.displayName = 'Button'

export default Button
...