reactjs - how - ¿Qué significa el error "El tipo de elemento JSX ''...'' no tiene ninguna construcción o firma de llamada"?
styled component material ui (5)
Cuando convierto de JSX a TSX y mantenemos algunas bibliotecas como js / jsx y convierto otras a ts / tsx, casi siempre olvido cambiar las declaraciones de importación js / jsx en los archivos TSX / TS de
import * as ComponentName from "ComponentName";
a
import ComponentName from "ComponentName";
Si llama a un antiguo componente de estilo JSX (React.createClass) desde TSX, use
var ComponentName = require("ComponentName")
Escribí un código:
function renderGreeting(Elem: React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
Recibo un error:
El tipo de elemento JSX
Elem
no tiene ninguna construcción o firma de llamada
Qué significa eso?
Esta es una confusión entre constructores e instancias .
Recuerde que cuando escribe un componente en React:
class Greeter extends React.Component<any, any> {
render() {
return <div>Hello, {this.props.whoToGreet}</div>;
}
}
Lo usas de esta manera:
return <Greeter whoToGreet=''world'' />;
No lo usas de esta manera:
let Greet = new Greeter();
return <Greet whoToGreet=''world'' />;
En el primer ejemplo, estamos pasando a
Greeter
, la
función constructora
de nuestro componente.
Ese es el uso correcto.
En el segundo ejemplo, estamos pasando una
instancia
de
Greeter
.
Eso es incorrecto y fallará en tiempo de ejecución con un error como "El objeto no es una función".
El problema con este código
function renderGreeting(Elem: React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
es que espera una
instancia
de
React.Component
.
Lo que quieres es una función que tome
un constructor
para
React.Component
:
function renderGreeting(Elem: new() => React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
o similarmente:
function renderGreeting(Elem: typeof React.Component) {
return <span>Hello, <Elem />!</span>;
}
Si desea tomar una clase de componente como parámetro (frente a una instancia), use
React.ComponentClass
:
function renderGreeting(Elem: React.ComponentClass<any>) {
return <span>Hello, <Elem />!</span>;
}
Si está utilizando material-ui , vaya a la definición de tipo del componente, que TypeScript subraya. Lo más probable es que veas algo como esto
export { default } from ''./ComponentName'';
Tiene 2 opciones para resolver el error:
1.Agregue
.default
cuando use el componente en JSX:
import ComponentName from ''./ComponentName''
const Component = () => <ComponentName.default />
2. Cambie el nombre del componente, que se exporta como "predeterminado", al importar:
import { default as ComponentName } from ''./ComponentName''
const Component = () => <ComponentName />
De esta manera, no necesita especificar
.default
cada vez que usa el componente.
Si realmente no te interesan los accesorios, el tipo más amplio posible es
React.ReactType
.
Esto permitiría pasar elementos dom nativos como una cadena.
React.ReactType
cubre todo esto:
renderGreeting(''button'');
renderGreeting(() => ''Hello, World!'');
renderGreeting(class Foo extends React.Component {
render() {
return ''Hello, World!''
}
});