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

7

我很难理解 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>
         )
     }
 }

但是我收到了这个错误

无效的component属性,类型为object,提供给Route组件,期望为function类型。

但是当我直接将组件A传递给Route组件时,它可以正常渲染。

当我在组件C的渲染函数内部使用console.log输出组件A时,我得到的是一个函数,但是当我在组件C的渲染函数内部使用console.log输出组件B时,我得到的是一个对象

我错过了什么?


你为什么想要使用 cloneElement - Heartbit
因为我想从“组件B”传递props到“组件A”...这是我的项目要求。 - besrabasant
1
我认为你应该使用 HOC 来实现这个目的。 - Heartbit
@SaeidAlidadi 所以你建议我将 Component B 设为 HOC - besrabasant
CloneElement 究竟是什么?我看到过使用该函数来克隆 React 组件的 children 的示例。@SaeidAlidadi - besrabasant
显示剩余3条评论
1个回答

17

首先,您需要了解React组件和React元素之间的区别。它们实际上是不同的。

具体来说,在jsx中,对于您的情况,A是一个React component,而<A />是一个React element。如果查看React.cloneElement文档,则它期望第一个参数是一个element,但是这里您传递了一个component。因此,您需要做的第一次更改是像这样将一个元素传递给React.cloneElement

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

第二个问题是 Route 组件期望一个 react组件 作为 component prop,但是 React.cloneElement 返回的是一个 react元素 而不是组件(也就是说,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。您可以从 B.js 返回一个组件,它渲染 A。这只是为了帮助理解。


2
明白了。解释得非常清楚。 - besrabasant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接