与Typescript EventHandler类型检查问题反应(onClick)

时间:2020-03-27 11:17:25

标签: reactjs typescript

这些天我一直在用Typescript练习React。

我的PropsType如下

export type PropType = {
  ingredientAdded: (type: keyof IngredientType) => void;
}

const buildControl: React.FunctionComponent<PropType> = (props) => (
  <div className={classes.BuildControl}>
    <div className={classes.Label}>{props.label}</div>
    <button className={classes.Less}>Less</button>
    <button className={classes.More} onClick={props.ingredientAdded as any}>More</button>
  </div>
);

身体。

这里的问题是,如果不进行强制转换,我将无法通过onClick={props.ingredientAdded}

当我查看onClick类型时,它会给我

onClick?: MouseEventHandler<T>;
type MouseEventHandler<T = Element> = EventHandler<MouseEvent<T>>;

似乎ingredientAdded: (type: keyof IngredientType) => void;函数类型对onClick无效。

但是有效。

我的问题是,这里的类型检查而不是强制转换为任何

的正确方法是什么?

修改

父组件传递了该函数。

type PropsType = {
  ingredientAdded(type: keyof IngredientType): void;
  ingredientRemoved(type: keyof IngredientType): void;
}

const controls: { label: string, type: keyof IngredientType }[] = [
  { label: 'Salad', type: 'salad' },
  { label: 'Bacon', type: 'bacon' },
  { label: 'Cheese', type: 'cheese' },
  { label: 'Meat', type: 'meat' },
];

const buildControls: React.FunctionComponent<PropsType> = (props) => (
  <div className={classes.BuildControls}>
    {controls.map(ctrl => (
      <BuildControl
        ingredientAdded={() => props.ingredientAdded(ctrl.type)}
        ingredientRemoved={() => props.ingredientRemoved(ctrl.type)}
        key={ctrl.label} label={ctrl.label} />
    ))}
  </div>
);

export default buildControls;

2 个答案:

答案 0 :(得分:0)

请尝试将props.ingredientAdded包装在函数中。

没有点击事件

const buildControl: React.FunctionComponent<PropType> = (props) => (
  <div className={classes.BuildControl}>
    <div className={classes.Label}>{props.label}</div>
    <button className={classes.Less}>Less</button>
    <button className={classes.More} onClick={() => { props.ingredientAdded() }}>More</button>
  </div>
);

具有点击事件

const buildControl: React.FunctionComponent<PropType> = (props) => (
  <div className={classes.BuildControl}>
    <div className={classes.Label}>{props.label}</div>
    <button className={classes.Less}>Less</button>
    <button className={classes.More} onClick={(event: React.MouseEvent) => { props.ingredientAdded(event) }}>More</button>
  </div>
);

答案 1 :(得分:0)

这是因为React上的onClick希望您传递的函数带有一个单独的参数,即Mouse Event。

您可以通过两种方式解决它:

  1. 用箭头功能包装onClick
  // ...
  onClick={ (event) => { props.ingredientAdded(type) } }
  1. (最好的方法!)在按钮的子组件上执行此逻辑,这样您的事件处理程序将不会明确知道ingredientAdded的依赖性:

interface IngredientType {
  type: string;
}

export type PropType = {
  handler: (type: keyof IngredientType) => void;
  type: keyof IngredientType;
};

const MoreButton: React.FunctionComponent<PropType> = props => {
  const handleClick = () => {
    props.handler(props.type);
  };

  return <button onClick={handleClick}>More</button>;
};

const MainComponent = ({ingredientAdded, type}) => {
  return <MoreButton handler={ingredientAdded} type={type} />
}

Check the example for the second way.