在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
}
答案 0 :(得分:2)
你所指的“React默认道具”又名“每个道具React已经知道”更恰当地称为“任何React DOM元素包装器组件接受的道具”,即onClick
,{{1等等。
默认道具通常是指className
上的静态defaultProps
属性,您可以使用该属性为未传递给组件的任何道具提供默认值。
React.Component
,onClick
等不是保留的道具名称,您可以在自己的组件中使用它们,例如,您可以让您的组件期望className
成为一个函数(无论它是否是个好主意)。对于任何类型的React元素(在撰写本文时)起作用的唯一保留的道具名称是className
和key
,并且它们不是真正的道具,因为它们不适用于您的组件渲染方法。
将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>
);
}
}