Javascript 函数作为 React 子元素无效。如果您返回一个组件而不是从渲染中返回,则可能会发生这种情况

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48458334/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:07:44  来源:igfitidea点击:

Functions are not valid as a React child. This may happen if you return a Component instead of from render

javascriptreactjshigher-order-components

提问by learner

I have written a Higher Order Component:

我写了一个高阶组件:

import React from 'react';


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

export default NewHOC;

I am using the above in my App.js:

我在我的 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>
   );
  }
 }

But, the warning I am getting is:

但是,我收到的警告是:

Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it. in NewHOC (created by App) in div (created by App) in App

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

The Movie.js file is:

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>
    }
}

What am I doing wrong?

我究竟做错了什么?

采纳答案by Sagiv b.g

You are using it as a regular component, but its actually a function that returns a component.

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

Try doing something like this:

尝试做这样的事情:

const NewComponent = NewHOC(Movie)

And you will use it like this:

你会像这样使用它:

<NewComponent someProp="someValue" />

Here is a running example:

这是一个运行示例:

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"/>

So basically NewHOCis just a function that accepts a component and returns a new component that renders the component passed in. We usually use this pattern to enhance components and share logic or data.

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

You can read about HOCS in the docsand i also recommend reading about the difference between react elements and components

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

I wrote an articleabout the different ways and patterns of sharing logic in react

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

回答by Stefan Michev

In my case i forgot to add the () after the function name inside the render function of a react component

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

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

       return ctrl;
    };


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

Changing the render method, as it states in the error message to

更改渲染方法,因为它在错误消息中指出

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

fixed the problem

解决了问题

回答by Vishal Gupta

Adding to sagiv's answer, we should create the parent component in such a way that it can consist all children components rather than returning the child components in the way you were trying to return.

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

Try to intentiate the parent component and pass the props inside it so that all children can use it like below

尝试意向父组件并在其中传递道具,以便所有孩子都可以像下面一样使用它

const NewComponent = NewHOC(Movie);

Here NewHOC is the parent component and all its child are going to use movie as props.

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

But any way, you guyd6 have solved a problem for new react developers as this might be a problem that can come too and here is where they can find the solution for that.

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

回答by Ricardo Tamarán Nú?ez Monzón

In my case, I was transport class component from parent and use it inside as a prop var, using typescript and Formik, and run well like this:

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

Parent 1

家长 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>
  }
}

Parent 2

家长 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>
        )
      }}
    />
    )
  }
}

回答by That's Enam

it also happens when you call a function from jsx directly rather than in an event. like

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

it will show the error if you write like

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

<h1>{this.myFunc}<h2>

it will go if you write:

如果你写,它会去:

<h1 onClick={this.myFunc}>Hit Me</h1>

回答by GumZ

I was able to resolve this by using my calling my high order component before exporting the class component. My problem was specifically using react-i18nextand its withTranslation method, but here was the solution:

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

export default withTranslation()(Header);

And then I was able to call the class Component as originally I had hoped:

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

<Header someProp={someValue} />

回答by OZZIE

I was getting this from webpack lazy loading like this

我是从这样的 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
});    

回答by Mwa Joe

What would be wrong with doing;

这样做会有什么问题;

<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;
   }
 })()}