reactjs - Hur man skickar resten av props till en react-komponent samtidigt som man har definierade nödvändiga props i ett interface
Så är detta samma problem, eller missar jag bara något?
import * as React from 'react';
interface Props {
value: string;
}
const MyComponent = (props: Props) => {
const { value, ...rest } = props;
return (
<input {...rest} type="text" value={value} />
);
}
interface ParentState {
searchText: string;
}
class ParentComponent extends React.Component<{}, ParentState> {
state: ParentState = {
searchText: ''
};
onSearchTextChanged = (e: React.FormEvent<HTMLInputElement>) => {
this.setState({
searchText: e.currentTarget.value
});
}
render() {
const { searchText } = this.state;
return (
<div>
<h2>Some Text</h2>
<MyComponent value={searchText} onChange={this.onSearchTextChanged} className="search-input" placeholder="Enter text"/>
// Errors here
</div>
)
}
}
export default ParentComponent
När jag har mina props för MyComponent definierade i ett gränssnitt får jag följande fel:
fel TS2339: Egenskapen 'onChange' finns inte på typen 'IntrinsicAttributes & Props'.
Men om jag ändrar props-typen till any, kompilerar det utan problem.
const MyComponent = (props: any) => {
Är det möjligt att definiera props i ett interface så att det finns specifika props som är obligatoriska, men också tillåta att ytterligare props skickas in så att jag inte behöver lägga till dem uttryckligen i interfacet?
Jag använder TypeScript 2.3.4 och React 15.5.4.
Svar #1
Om du vill vidarebefordra alla egenskaper hos input-elementet inuti MyComponent till props för MyComponent kan du slå upp vilka props input har (i VSCode till exempel, använd gå till definition medan du är på input-taggen).
interface IntrinsicElements {
....
input: React.DetailedHTMLProps<React.InputHTMLAttributes<>, HTMLInputElement>;
....
}
Vi kan använda React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement> som basklass för våra props och vi får alla egenskaper hos input. Eftersom DetailedHTMLProps bara lägger till ref till React.InputHTMLAttributes<HTMLInputElement> kan vi bara använda React.InputHTMLAttributes<HTMLInputElement> som basgränssnitt för att få alla input-egenskaper utom ref:
import * as React from 'react'
interface Props extends React.InputHTMLAttributes<HTMLInputElement> {
value: string;
}
const MyComponent = (props: Props) => {
const { value, ...rest } = props;
return (
<input {...rest} type="text" value={value} />
);
}
// Usage
interface ParentState { searchText :string }
class ParentComponent extends React.Component<{}, ParentState> {
state: ParentState = {
searchText: ''
};
onSearchTextChanged = (e: React.FormEvent<HTMLInputElement>) => {
this.setState({
searchText: e.currentTarget.value
});
}
render() {
const { searchText } = this.state;
return (
<div>
<h2>Some Text</h2>
<MyComponent value={searchText} onChange={this.onSearchTextChanged} className="search-input" placeholder="Enter text"/>
</div>
)
}
}
export default ParentComponent
Svar #2
Du kan undvika överflödiga egenskaps-/attributkontroller genom att lägga till en strengindexsignatur till ditt gränssnitt:
interface Props {
value: string;
// This is a string index signature.
// This means that all properties in 'Props' are assignable to
// the empty object type ({})
[propName: string]: {};
}
Du skulle också kunna skriva [propName: string]: any, men det gör det generellt sett mindre säkert att använda i MyComponent själv.
