解决React报错JSX element type does not have any construct or call signatures

目录
  • 总览
  • React.ElementType
  • 传递JSX元素
  • 更新类型包

总览

当我们试图将元素或react组件作为属性传递给另一个组件,但是属性的类型声明错误时,会产生"JSX element type does not have any construct or call signatures"错误。为了解决该错误,可以使用React.ElementType类型。

这里有个例子来展示错误是如何发生的。

// App.tsx
import React from 'react';
interface Props {
  comp: JSX.Element;
}
const Wrapper: React.FunctionComponent<Props> = props => {
  const {comp: Comp} = props;
  // ️ JSX element type 'Comp' does not have any construct or call signatures.ts(2604)
  return (
    <div>
      <Comp name="James" />
    </div>
  );
};
const App: React.FunctionComponent = () => {
  const heading = ({name}: {name: string}) => <h2>Hello {name}</h2>;
  return (
    <div>
      <Wrapper comp={heading} />
    </div>
  );
};
export default App;

我们尝试将一个React组件作为属性传递给Wrapper组件,但我们将该React组件的类型声明为JSX.Element

React.ElementType

为了解决该错误,将属性的类型声明为React.ElementType

// App.tsx
import React from 'react';
interface Props {
  comp: React.ElementType; // ️ type it as React.ElementType
}
const Wrapper: React.FunctionComponent<Props> = props => {
  // ️ component names must start with capital letter
  const {comp: Comp} = props;
  return (
    <div>
      <Comp name="James" />
    </div>
  );
};
const App: React.FunctionComponent = () => {
  // ️ takes a name prop
  const heading = ({name}: {name: string}) => <h2>Hello {name}</h2>;
  return (
    <div>
      <Wrapper comp={heading} />
    </div>
  );
};
export default App;

请注意,React.ElementType可以为元素期望的属性类型传递一个泛型。

在这个例子中,我们必须传递给它一个具有字符串类型的name属性的对象,因为那是heading组件接收的属性。

// App.tsx
import React from 'react';
interface Props {
  //  explicitly type props comp takes
  comp: React.ElementType<{name: string}>;
}
const Wrapper: React.FunctionComponent<Props> = props => {
  // ️ component names must start with capital letter
  const {comp: Comp} = props;
  return (
    <div>
      <Comp name="James" />
    </div>
  );
};
const App: React.FunctionComponent = () => {
  const heading = ({name}: {name: string}) => <h2>Hello {name}</h2>;
  return (
    <div>
      <Wrapper comp={heading} />
    </div>
  );
};
export default App;

现在我们显式地声明了元素在使用时所接受的comp属性的类型。这有助于我们在向组件传递属性时利用IDE的自动完成功能。

我们也可以使用React.ComponentType,但这样我们就需要对属性声明类型。

// App.tsx
import React from 'react';
interface Props {
  // ️ now using React.ComponentType ️
  comp: React.ComponentType<{name: string}>;
}
const Wrapper: React.FunctionComponent<Props> = props => {
  // ️ component names must start with capital letter
  const {comp: Comp} = props;
  return (
    <div>
      <Comp name="James" />
    </div>
  );
};
const App: React.FunctionComponent = () => {
  const heading = ({name}: {name: string}) => <h2>Hello {name}</h2>;
  return (
    <div>
      <Wrapper comp={heading} />
    </div>
  );
};
export default App;

React.ComponentType 中的泛型不能默认为any类型,因此我们需要显示地声明属性的类型。

传递JSX元素

如果你需要将JSX元素作为属性传递给组件,并且不是一个真正的组件,那么使用JSX.Element类型就是正确的。

// App.tsx
import React from 'react';
interface Props {
  // ️ using JSX.Element type
  comp: JSX.Element;
}
const Wrapper: React.FunctionComponent<Props> = props => {
  const {comp: Comp} = props;
  // ️ use as {Comp}
  return <div>{Comp}</div>;
};
const App: React.FunctionComponent = () => {
  const Heading = ({name}: {name: string}) => <h2>Hello {name}</h2>;
  // ️ we are passing an actual JSX element
  // because we didn't pass it as comp={Heading}
  return (
    <div>
      <Wrapper comp={<Heading name="James" />} />
    </div>
  );
};
export default App;

我们将comp属性的类型声明为JSX.Element,因为我们传递了一个真正的JSX元素(不是组件)到Wrapper组件上。

我们传递了一个JSX元素,是因为我们将comp={<Heading />}作为属性进行传递,而不是comp={(props) => <h2>Hello world</h2>}

需要注意的是,在第一种情况下,我们传递的是一个JSX元素属性。而在第二种情况下,我们传递的是一个返回JSX元素的函数(一个功能组件)。

在Wrapper组件中,我们不应尝试使用JSX元素作为组件。比如说,不要这么写<Comp />,而要这么写{Comp}

我们没有传递一个真正的组件作为属性,我们传递的是一个JSX元素,所以它不应该作为一个组件使用。

更新类型包

如果前面的建议都没有帮助,试着通过运行以下命令来更新你的React类型的版本。

# ️ with NPM
npm install react@latest react-dom@latest
npm install --save-dev @types/react@latest @types/react-dom@latest
# ----------------------------------------------
# ️ with YARN
yarn add react@latest react-dom@latest
yarn add @types/react@latest @types/react-dom@latest --dev

原文链接:bobbyhadz.com/blog/react-…

以上就是解决React报错JSX element type does not have any construct or call signatures的详细内容,更多关于React JSX element报错解决的资料请关注我们其它相关文章!

(0)

相关推荐

  • 解决React报错Encountered two children with the same key

    目录 总览 index 唯一标识 总览 当我们从map()方法返回的两个或两个以上的元素具有相同的key属性时,会产生"Encountered two children with the same key"错误.为了解决该错误,为每个元素的key属性提供独一无二的值,或者使用索引参数. 这里有个例子来展示错误是如何发生的. // App.js const App = () => { // ️ name property is not a unique identifier con

  • 解决React报错Style prop value must be an object

    目录 总览 映射 提取 总览 在React中,当我们为元素的style 属性传递字符串时,会产生"Style prop value must be an object"警告.为了解决该警告,使用从属性到值的映射.比如说,style={{paddingLeft: '15px'}} . 这里有个例子来展示错误是如何发生的. // App.js const App = () => { // ️ Style prop value must be an object eslint(reac

  • 解决React报错Cannot assign to 'current' because it is a read-only property

    目录 总览 正确的泛型 DOM元素 总览 当我们用一个null值初始化一个ref,但在其类型中不包括null时,就会发生"Cannot assign to 'current' because it is a read-only property"错误.为了解决该错误,请在ref的类型中包含null.比如说,const ref = useRef<string | null>(null) . 这里有个例子来展示错误是如何发生的. // App.tsx import {useEf

  • 解决React报错useNavigate() may be used only in context of Router

    目录 总览 useNavigate Jest replace 总览 当我们尝试在react router的Router上下文外部使用useNavigate 钩子时,会产生"useNavigate() may be used only in the context of a Router component"警告.为了解决该问题,只在Router上下文中使用useNavigate 钩子. 下面是一个在index.js文件中将React应用包裹到Router中的例子. // index.j

  • 解决React报错Unexpected default export of anonymous function

    目录 总览 命名 注释单行规则 总结 总览 当我们尝试使用默认导出来导出一个匿名函数时,会导致"Unexpected default export of anonymous function"警告.为了解决该错误,在导出函数之前,为函数赋予一个名称. 这里有个例子来展示警告是如何发生的. // Header.js // ️ default export for anonymous function // ️ Unexpected default export of anonymous

  • 解决React报错Functions are not valid as a React child

    目录 总览 调用函数 总结 总览 产生"Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render."错误 通常是因为以下两个原因: 从render中返回一个函数引用而不是一个组件. 使用 react router 路由作为<Route path="/about" el

  • 解决React报错The tag is unrecognized in this browser

    目录 总览 确保标签存在 小写字母开头 总览 当我们使用一个在浏览器中不存在的标签或以小写字母开头的组件名称时,会产生"The tag is unrecognized in this browser"React警告.为了解决该问题,只使用有效的标签名称,并将你的组件的第一个字母大写. 这里有个例子来展示错误是如何发生的. // App.js const App = () => { // ️ Warning: The tag <p1> is unrecognized i

  • 解决React报错Expected `onClick` listener to be a function

    目录 总览 传递函数 传递参数 总览 当我们为元素的onClick属性传递一个值,但是该值却不是函数时,会产生"Expected onClick listener to be a function"报错.为了解决该报错,请确保只为元素的onClick属性传递函数. 这里有个例子来展示错误是如何发生的. // App.js const App = () => { // ️ Warning: Expected `onClick` listener to be a function /

  • 解决React报错Property does not exist on type 'JSX.IntrinsicElements'

    目录 总览 组件大写 类型声明 总结 总览 当组件名称以小写字母开头时,会导致"Property does not exist on type 'JSX.IntrinsicElements'"错误.为了解决该错误,确保组件名称总是以大写字母开头,安装React声明文件并重启你的开发服务器. 这里有个示例用来展示错误是如何发生的. // App.tsx // ️ name starts with lowercase letter function myComponent() { retu

  • 解决React报错Property 'X' does not exist on type 'HTMLElement'

    目录 总览 类型断言 总结 总览 在React中,当我们试图访问类型为HTMLElement 的元素上不存在的属性时,就会发生Property 'X' does not exist on type 'HTMLElement'错误.为了解决该错误,在访问属性之前,使用类型断言来正确地类型声明元素. 这里有三个例子来展示错误是如何发生的. // App.tsx import {useEffect} from 'react'; export default function App() { useEf

  • 解决React报错Parameter 'props' implicitly has an 'any' type

    目录 总览 安装类型文件 声明类型 泛型 重新安装 总览 当我们没有为函数组件或者类组件的props声明类型,或忘记为React安装类型声明文件时,会产生"Parameter 'props' implicitly has an 'any' type"错误.为了解决这个错误,在你的组件中明确地为props对象设置一个类型. 安装类型文件 你首先要确定的是你已经安装了React类型声明文件.在项目的根目录下打开终端,并运行以下命令. # ️ with NPM npm install --s

  • 解决React报错Property 'value' does not exist on type EventTarget

    目录 总览 正确声明类型 找出类型 总结 总览 当event参数的类型不正确时,会产生"Property 'value' does not exist on type EventTarget"错误.为了解决该错误,将event的类型声明为React.ChangeEvent<HTMLInputElement> .然后就可以通过event.target.value 来访问其值. 这里有个示例用来展示错误是如何发生的. // App.tsx function App() { //

  • 解决React报错React.Children.only expected to receive single React element child

    目录 总览 React片段 DOM元素 总览 当我们把多个子元素传递给一个只期望有一个React子元素的组件时,会产生"React.Children.only expected to receive single React element child"错误.为了解决该错误,将所有元素包装在一个React片段或一个封闭div中. 这里有个示例来展示错误是如何发生的. // App.js import React from 'react'; function Button(props)

  • 解决React报错Expected an assignment or function call and instead saw an expression

    目录 正文 显式返回 隐式返回 返回对象 正文 当我们忘记从函数中返回值时,会产生"Expected an assignment or function call and instead saw an expression"错误.为了解决该错误,确保显式地使用return语句或使用箭头函数隐式返回. 下面有两个示例来展示错误是如何产生的. // App.js const App = props => { const result = ['a', 'b', 'c'].map(el

  • 解决React报错You provided a `checked` prop to a form field

    目录 总览 defaultChecked onChange 初始值 总览 当我们在多选框上设置了checked 属性,却没有onChange 处理函数时,会产生"You provided a checked prop to a form field without an onChange handler"错误.为了解决该错误,可以使用defaultChecked 属性,或者在表单字段上设置onChange 属性. 这里有个例子用来展示错误是如何发生的. // App.js export

  • 解决React报错Cannot find namespace context

    目录 总览 tsx 安装@types/包 手动添加 总览 在React中,为了解决"Cannot find namespace context"错误,在你使用JSX的文件中使用.tsx扩展名,在你的tsconfig.json文件中把jsx设置为react-jsx,并确保为你的应用程序安装所有必要的@types包. 这里有个例子来展示错误是如何发生的. // App.ts import React from 'react'; interface UserCtx { first: stri

随机推荐