用自定义道具加入React道具

时间:2017-10-31 18:35:52

标签: reactjs typescript

在React中使用Typescript定义道具时,似乎默认的React道具会被接口覆盖。是否有一种干净的方法来合并两者而不必指定React已经知道的每个道具?

示例:

interface IProps { // extends React.???
   title: string;
   // Generally seen adding children?: any
   // But this can get out of hand with onClick, onChange, etc
}

function MyComponent(props: IProps) {
   return props.children; // Typescript error: children doesn't exist on props
}

2 个答案:

答案 0 :(得分:2)

你所指的“React默认道具”又名“每个道具React已经知道”更恰当地称为“任何React DOM元素包装器组件接受的道具”,即onClick,{{1等等。

默认道具通常是指className上的静态defaultProps属性,您可以使用该属性为未传递给组件的任何道具提供默认值。

React.ComponentonClick等不是保留的道具名称,您可以在自己的组件中使用它们,例如,您可以让您的组件期望className成为一个函数(无论它是否是个好主意)。对于任何类型的React元素(在撰写本文时)起作用的唯一保留的道具名称是classNamekey,并且它们不是真正的道具,因为它们不适用于您的组件渲染方法。

ref传递给您自己的组件不会自动注册点击处理程序。只有当您将收到的onClick传递给onClick<div>或其他React DOM Element包装器时,才会执行此操作。 如果你没有对你传递的道具做任何事情,它没有效果(除了可能导致纯渲染组件更新,否则不会)。

例如,以下组件不会响应点击次数:

<button>

但以下是:

const ClickFail = props => <button />
render(<ClickFail onClick={...} />, document.getElementById('root'))

如果您真的想要,可以将const ClickSuccess = props => <button onClick={props.onClick} /> render(<ClickSuccess onClick={...} />, document.getElementById('root')) 传递给只有一个子元素:

onClick

或者您可以使用不同的名称传递多个点击处理程序:

const ClickButtonOnly = props => (
  <form>
    <input placeholder="ignores clicks" />
    <button onClick={props.onClick}>Handles Clicks</button>
  </form>
)

另请注意,某些DOM元素包装器接受其他人不的道具,例如const SimpleForm = props => ( <form> <button onClick={props.onCancelClick}>Cancel</button> <button onClick={props.onOKClick}>OK</button> </form> ) 仅适用于readOnly<input>

您甚至可以要求<textarea>为您想要的任何类型。例如,您可以将一个函数作为组件的children传递并使用它(再次,不是React的最佳用途,而只是为了说明可能的内容:

children

所以你看,type Props = { value: number, children: (value: number) => number, } const ApplyFunction = (props: Props) => ( <div>{React.Children.only(props.children)(props.value)}</div> ) render( <ApplyFunction value={3}> {value => value * value} </ApplyFunction>, document.getElementById('root') ) // renders <div>9</div> 不一定要扩展任何东西。

然而,通常将rest props传递给React DOM Element包装器(例如IProps并且正如您所问的那样,能够检查所有这些输入属性的类型会很好你的组件。

我认为您可以使用Flow执行以下操作以正确检查类型,但不幸的是我认为没有任何与Typecript相同的内容(如果我错了,有人会纠正我):

<div {...props}>...</div>

答案 1 :(得分:0)

您应该定义无状态功能组件将返回React.SFC<YourProps>

试试这个

import * as React from "react";
const MyComponent: React.SFC<IProps> = (props) => {
  return props.children;
}

如果您想使用基于类的组件,可以使用React.Component<YourProps(optional), YourState(optional)>来扩展您的课程

例如

import * as React from "react"
class MyComponent extends React.Component<IProps> {
  public render(): JSX.Element {
    return (
      <div>...</div>
    );
  }
}