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

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

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

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


person learner    schedule 26.01.2018    source источник
comment
Вы используете его как обычный родительский компонент. я думаю, вам следует что-то сделать в этом направлении: const newComponent = NewHOC(Movie )   -  person Sagiv b.g    schedule 26.01.2018
comment
Спасибо. Это решает проблему.   -  person learner    schedule 26.01.2018
comment
Отлично, я просто добавил это как ответ :)   -  person Sagiv b.g    schedule 26.01.2018


Ответы (10)


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

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

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 в документации, и я также рекомендую прочитать о разница между реагирующими элементами и компонентами

Я написал статью о различных способах и шаблонах совместного использования логики в реакции.

person Sagiv b.g    schedule 26.01.2018
comment
Не могли бы вы подробнее объяснить свой ответ? У меня такая же проблема с предупреждением - person Oximer; 01.10.2018
comment
@Oximer Что ты не понял? - person Sagiv b.g; 01.10.2018
comment
Где вы должны реализовать этот код, я прав? @Oximer - person OuuGiii; 30.10.2018
comment
проголосовали против, потому что это ничего не объясняет и не дает дальнейшего чтения по этому вопросу. Даже OP не объяснил, насколько он / она считает этот ответ ценным. Загадочные ответы хуже, чем отсутствие ответа. Контекст - это все. Никто из читателей не может знать наверняка, ГДЕ разместить этот фрагмент кода. Кроме того, само объяснение не имеет смысла: оно имеет смысл только в том случае, если детали реализации в React дают поверхностную оценку выражения, поскольку функции, как известно, являются гражданами 1-го класса в Javascript. - person Yoshimitsu; 01.11.2018
comment
У меня создалось впечатление, что это очевидная функция, возвращающая новый компонент. в любом случае я добавил работающий пример и ссылку в документы. - person Sagiv b.g; 01.11.2018
comment
Есть ли новый синтаксис, позволяющий избежать ввода двух строк? - person Minh Nghĩa; 31.10.2020
comment
@ MinhNghĩa Какой инес? - person Sagiv b.g; 31.10.2020

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

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

       return ctrl;
    };


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

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

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

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

person Stefan Michev    schedule 10.04.2019

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

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

const NewComponent = NewHOC(Movie);

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

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

person Vishal Gupta    schedule 24.10.2018

Я смог решить эту проблему, вызвав свой компонент высокого порядка перед экспортом компонента класса. Моя проблема заключалась в использовании react-i18next и его метода withTranslation, но вот решение:

export default withTranslation()(Header);

И тогда я смог вызвать класс Component, как я изначально надеялся:

<Header someProp={someValue} />
person GumZ    schedule 06.01.2020

Я столкнулся с этой ошибкой, следуя приведенным здесь инструкциям: https://reactjs.org/docs/add-react-to-a-website.html

Вот что у меня было:

ReactDOM.render(Header, headerContainer);

Должен быть:

ReactDOM.render(React.createElement(Header), headerContainer);
person BL1133    schedule 10.04.2021

это также происходит, когда вы вызываете функцию из jsx напрямую, а не в событии. нравиться

он покажет ошибку, если вы напишите как

<h1>{this.myFunc}<h2>

пойдет, если вы напишете:

<h1 onClick={this.myFunc}>Hit Me</h1>
person That's Enam    schedule 20.11.2019

Я получал это из-за ленивой загрузки 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
});    
person OZZIE    schedule 31.01.2020

В моем случае я был компонентом транспортного класса от родителя и использовал его внутри как prop var, используя машинописный текст и 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>
        )
      }}
    />
    )
  }
}
person Ricardo Tamarán Núñez Monzón    schedule 14.01.2019

Что было бы неправильно делать;

<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;
   }
 })()}
person Joe Mwa    schedule 26.05.2020

В моем случае я забыл удалить эту часть '() = ›'. Глупая ошибка ctrl + c + v.

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

Так должно быть так:

const Account = ({ name }) => {
person MichalPr    schedule 09.07.2021