React.CloneElement 返回一个对象而不是函数

React.CloneElement returning an object instead of function

我很难理解 React.cloneElement() 函数的行为

我的组件结构是这样的

A.js

export default class A extends React.Component {
     render() {
         return (<h1>{ this.props.message }</h1>)
     }
 }

B.js

import A from "./A"

const newComponent = React.cloneElement(A,{
    message: "Hello World"
})

export default newComponent

C.js

import B from "./B"
import { BrowserRouter as Router, Route } from "react-router-dom"

// To Be very precise
 export default class C extends React.Component {
     render() {
         return (
             <Router>
                <Route path="/" component={B}  />
            </Router>
         )
     }
 }

但是我得到这个错误

提供给 Routeobject 类型的无效道具 component,应为 function

但是当我将组件 A 直接传递给 Route 组件时,它呈现得很好。

当我 console.log Component A inside the render function of Component C 时,我得到了一个函数但是 当我在 Component C 的 render 函数中 console.log Component B 时,我得到一个对象

我错过了什么?

首先你需要了解difference between React component and React element。两者其实是不同的。

具体来说 jsx,在您的情况下,A 是反应 component<A /> 是反应 element。如果您查看 React.cloneElement 文档,那么它期望 element 作为第一个参数,但在这里您传递的是 component。因此,您需要做的第一个更改是像这样

将一个元素传递给 React.cloneElement
const newComponent = React.cloneElement(<A />,{
    message: "Hello World"
})

第二件事是 Route 组件期望 react component 作为 component prop,但是 React.cloneElement return 是 react element 而不是组件(这意味着 newComponent 是一个元素,而不是组件)。因此,您不能简单地从 B.js 文件中导出 newComponent。您必须改为导出 component。为此,您可以创建 class component/stateless component。所以你的B.js应该看起来像这样

// B.js
import A from "./A"

const newComponent = React.cloneElement(<A />, {
  message: "Hello World"
})

export default class B extends React.Component {
  render() {
    return (<div>{newComponent}</div>)
  }
}

顺便说一下,在您的案例中,您甚至不需要 cloneElement。您可以简单地 return 来自 B.js 的组件,它呈现 A。这只是为了理解目的。