简体   繁体   English

将 forwardRef 与 proptypes 和 eslint 一起使用

[英]Using forwardRef with proptypes and eslint

I am trying to use forwardRef for a Button in a project using eslint and prop-types .我正在尝试使用eslintprop-types在项目中将 forwardRef 用于 Button 。

This is what I tried so far, and the errors I get each time:这是我到目前为止所尝试的,以及我每次得到的错误:

First attempt第一次尝试

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)

This will give me the following warning in the console: Warning: forwardRef render functions do not support propTypes or defaultProps. Did you accidentally pass a React component?这将在控制台中给我以下警告: Warning: forwardRef render functions do not support propTypes or defaultProps. Did you accidentally pass a React component? Warning: forwardRef render functions do not support propTypes or defaultProps. Did you accidentally pass a React component?

Second attempt第二次尝试

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;

I get: action is missing in props validation .我得到: action is missing in props validation

Third attempt第三次尝试

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;

This time, I get: Component definition is missing display name .这一次,我得到: Component definition is missing display name

So what is the correct way to do this?那么这样做的正确方法是什么?

You are almost done with your third attempt.您几乎完成了第三次尝试。 But you don't have to use twice forwardRef , the first use with the Button declaration is enough.但是您不必使用两次forwardRef ,第一次使用Button声明就足够了。 The display name rule is not an error (neither at JavaScript nor React level), but rather an intentional prop in order to show the "real" name of the component, used by React in debugging messages.显示名称规则不是错误(无论是在 JavaScript 还是 React 级别),而是为了显示组件的“真实”名称,React 在调试消息中使用的故意道具。 In your case, the forwardRef function will hide the "real" component name for the transpiler.在您的情况下, forwardRef函数将隐藏forwardRef的“真实”组件名称。

You can even disable this rule if it's a real problem to write displayName for each of those case.如果为每种情况编写displayName确实有问题,您甚至可以禁用此规则。

https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/display-name.md 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

const Form = React.forwardRef(function Form(
  { submitHandler, keyUpHandler, label, type, placeholder, buttonTxt },
  ref
) {

export default Form

No warnings doing this way.这样做没有警告。 function Form takes care of the name. function Form负责名称。

interface SomeProps {
 // written your props
};

const SomeFC = forwardRef((props:SomeProps,ref)=>{
// do something and returns
}})

Declare the type of props for inner FC can fix the proptypes warnning!声明内部 FC 的 props 类型可以修复 proptypes 警告!

Any idea how to resolve the displayName issue when using forwardRef and typescript?知道如何在使用 forwardRef 和 typescript 时解决 displayName 问题吗? This code throws an error when I try to build:当我尝试构建时,此代码会引发错误:

"error TS2339: Property 'displayName' does not exist on type" “错误 TS2339:类型上不存在属性 'displayName'”

interface Props {
    id: string,
    className: string,
    onClick: ()=> void
}

const MyComponent = React.forwardRef<
  HTMLUListElement,
  Props
>(({className, id, onClick}, ref) => {
  return (
    <ul ref={ref} className={className} id={id} onClick={onClick}>
        // some code here
    </ul>
  );
});

MyComponent.displayName = "MyComponent";

export { MyComponent };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM