Функции недействительны как ребенок Реактива. Это может произойти, если вы вернете компонент вместо рендеринга

Я написал компонент высшего порядка:

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 (создается приложением) в div (создается приложением) в приложении

Файл 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>
    }
}

Что я делаю неправильно?

Ответы

Ответ 1

Вы используете его как обычный компонент, но на самом деле это функция, которая возвращает компонент.

Попробуйте сделать что-то вроде этого:

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

Ответ 2

Добавляя к ответу sagiv, мы должны создать родительский компонент таким образом, чтобы он мог содержать все дочерние компоненты, а не возвращать дочерние компоненты так, как вы пытались вернуть.

Попробуйте создать родительский компонент и передать ему подпорки, чтобы все дети могли использовать его, как показано ниже.

const NewComponent = NewHOC(Movie);

Здесь NewHOC является родительским компонентом, и все его дочерние элементы будут использовать фильм в качестве реквизита.

Но, в любом случае, вы, guyd6, решили проблему для новых разработчиков, поскольку это может быть проблемой, которая может возникнуть и здесь, где они могут найти решение для этого.

Ответ 3

В моем случае я был компонентом класса транспорта из parent и использовал его внутри как prop var, используя typcript и 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 Parent2 extends React.Component{
  render(){
    const { componentToFormik } = this.props
    return(
    <Formik 
      render={(formikProps) => {
        return(
          <React.fragment>
            {(new componentToFormik(formikProps)).render()}
          </React.fragment>
        )
      }}
    />
    )
  }
}

Ответ 4

В моем случае я забыл добавить() после имени функции внутри функции рендеринга компонента реакции

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

       return ctrl;
    };


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

Изменение метода рендеринга, как указано в сообщении об ошибке, на

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

исправил проблему