102

我写了一个高阶组件:

import React from 'react';


const NewHOC = (PassedComponent) => {
    return class extends React.Component {
        render(){
            return (
                <div>
                    <PassedComponent {...this.props}/>
                </div>
            )
        }
    }
}

export default NewHOC;

我在我的 App.js 中使用上述内容:

import React from 'react';
import Movie from './movie/Movie';
import MyHOC from './hoc/MyHOC';
import NewHOC from './hoc/NewHOC';
export default class App extends React.Component {
  render() {
   return (
    <div>
     Hello From React!!
     <NewHOC>
        <Movie name="Blade Runner"></Movie>
     </NewHOC>
    </div>
   );
  }
 }

但是,我得到的警告是:

警告:函数作为 React 子级无效。如果您从渲染返回一个组件而不是 <Component />,则可能会发生这种情况。或者,也许您打算调用此函数而不是返回它。在 NewHOC(由 App 创建)在 div(由 App 创建)在 App

Movie.js 文件是:

import React from "react";

export default class Movie extends React.Component{
    render() {
        return <div>
            Hello from Movie {this.props.name}
            {this.props.children}</div>
    }
}

我究竟做错了什么?

4

12 回答 12

81

您将它用作常规组件,但它实际上是一个返回组件的函数。

尝试做这样的事情:

const NewComponent = NewHOC(Movie)

你会像这样使用它:

<NewComponent someProp="someValue" />

这是一个运行示例:

const NewHOC = (PassedComponent) => {
  return class extends React.Component {
    render() {
      return (
        <div>
          <PassedComponent {...this.props} />
        </div>
      )
    }
  }
}

const Movie = ({name}) => <div>{name}</div>

const NewComponent = NewHOC(Movie);

function App() {
  return (
    <div>
      <NewComponent name="Kill Bill" />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"/>

所以基本上NewHOC只是一个函数,接受一个组件并返回一个新组件,渲染传入的组件。我们通常使用这种模式来增强组件并共享逻辑或数据。

您可以在文档中阅读 HOCS,我还建议阅读有关反应元素和组件之间的区别

我写了一篇关于 React 中共享逻辑的不同方式和模式的文章。

于 2018-01-26T09:20:13.487 回答
29

在我的情况下,我忘记在反应组件的渲染函数内的函数名称之后添加 ()

public render() {
       let ctrl = (
           <>
                <div className="aaa">
                    {this.renderView}
                </div>
            </>
       ); 

       return ctrl;
    };


    private renderView() : JSX.Element {
        // some html
    };

更改渲染方法,如错误消息中所述

        <div className="aaa">
            {this.renderView()}
        </div>

解决了问题

于 2019-04-10T12:03:29.407 回答
27

我也确实遇到了这个错误,因为我在路由时没有使用正确的语法。这是在<Routes>部分下的我的 App.js 中:

错误的:

<Route path="/movies/list" exact element={ MoviesList } />

正确的:

<Route path="/movies/list" exact element={ <MoviesList/> } />

所以现在MoviesList被识别为一个组件。

于 2021-11-16T15:22:00.910 回答
5

我在按照此处的说明操作时遇到了这个错误:https ://reactjs.org/docs/add-react-to-a-website.html

这是我所拥有的:

ReactDOM.render(Header, headerContainer);

它应该是:

ReactDOM.render(React.createElement(Header), headerContainer);
于 2021-04-10T02:07:35.197 回答
3

添加到 sagiv 的答案中,我们应该以一种可以包含所有子组件的方式创建父组件,而不是以您尝试返回的方式返回子组件。

尝试初始化父组件并在其中传递道具,以便所有子组件都可以像下面这样使用它

const NewComponent = NewHOC(Movie);

这里 NewHOC 是父组件,它的所有子组件都将使用电影作为道具。

但是无论如何,您已经为新的 react 开发人员解决了一个问题,因为这可能也是一个可能出现的问题,在这里他们可以找到解决方案。

于 2018-10-24T19:02:04.010 回答
2

在导出类组件之前,我可以通过调用我的高阶组件来解决这个问题。我的问题是专门使用react-i18next它的 withTranslation 方法,但这里是解决方案:

export default withTranslation()(Header);

然后我能够像最初希望的那样调用类 Component :

<Header someProp={someValue} />
于 2020-01-06T22:40:43.897 回答
2

我也有这个错误。问题是如何调用该函数。

错误代码

const Component = () => {
    const id = ({match}) => <h2>Test1: {match.params.id}</h2>
    return <h1>{id}</h1>;
};

id是一个函数,所以:

正确的代码

return <h1>{id()}</h1>;
于 2021-11-21T18:55:41.607 回答
1

就我而言,我是从父级传输类组件,并在内部将其用作道具 var,使用 typescript 和 Formik,并且像这样运行良好:

家长 1

import Parent2 from './../components/Parent2/parent2'
import Parent3 from './../components/Parent3/parent3'

export default class Parent1 extends React.Component {
  render(){
    <React.Fragment>
      <Parent2 componentToFormik={Parent3} />
    </React.Fragment>
  }
}

家长 2

export default class Parent2 extends React.Component{
  render(){
    const { componentToFormik } = this.props
    return(
    <Formik 
      render={(formikProps) => {
        return(
          <React.fragment>
            {(new componentToFormik(formikProps)).render()}
          </React.fragment>
        )
      }}
    />
    )
  }
}
于 2019-01-14T13:27:12.670 回答
1

当您直接从 jsx 调用函数而不是在事件中调用函数时,也会发生这种情况。像

如果你这样写,它会显示错误

<h1>{this.myFunc}<h2>

如果你写它会去的:

<h1 onClick={this.myFunc}>Hit Me</h1>
于 2019-11-20T15:12:08.390 回答
1

我是从 webpack 延迟加载中得到这个的

import Loader from 'some-loader-component';
const WishlistPageComponent = loadable(() => import(/* webpackChunkName: 'WishlistPage' */'../components/WishlistView/WishlistPage'), {
  fallback: Loader, // warning
});
render() {
    return <WishlistPageComponent />;
}


// changed to this then it's suddenly fine
const WishlistPageComponent = loadable(() => import(/* webpackChunkName: 'WishlistPage' */'../components/WishlistView/WishlistPage'), {
  fallback: '', // all good
});    
于 2020-01-31T15:29:44.823 回答
1

这样做会有什么问题;

<div className="" key={index}>
   {i.title}
</div>

[/*Use IIFE */]

{(function () {
     if (child.children && child.children.length !== 0) {
     let menu = createMenu(child.children);
     console.log("nested menu", menu);
     return menu;
   }
 })()}
于 2020-05-26T14:20:48.470 回答
0

就我而言,我忘记删除这部分'() =>'。愚蠢的 ctrl+c+v 错误。

const Account = () => ({ name }) => {

所以它应该是这样的:

const Account = ({ name }) => {
于 2021-07-09T13:58:09.647 回答