web-dev-qa-db-fra.com

Les fonctions ne sont pas valides en tant qu'enfant de React. Cela peut arriver si vous retournez un composant au lieu de à partir du rendu

J'ai écrit un composant d'ordre supérieur:

import React from 'react';


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

export default NewHOC;

J'utilise ce qui précède dans mon 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>
   );
  }
 }

Mais l’avertissement que je reçois est le suivant:

Avertissement: Les fonctions ne sont pas valides en tant qu’enfants de React. Cela peut arriver si vous renvoyez un composant au lieu de de rendre. Ou peut-être vous vouliez appeler cette fonction plutôt que de la retourner . dans NewHOC (créé par App) in div (créé par App) dans l'application

Le fichier Movie.js est:

import React from "react";

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

Qu'est-ce que je fais mal?

23
learner

Vous l'utilisez en tant que composant standard, mais c'est en fait une fonction qui renvoie un composant. 

Essayez de faire quelque chose comme ça: 

const NewComponent = NewHOC(Movie)

Et vous allez l'utiliser comme ça: 

<NewComponent someProp="someValue" />

Voici un exemple en cours d'exécution: 

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

Donc, fondamentalement, NewHOC est simplement une fonction qui accepte un composant et retourne un nouveau composant qui rend le composant transmis. Nous utilisons généralement ce modèle pour améliorer les composants et partager la logique ou les données.

Vous pouvez lire sur HOCS dans docs et je vous recommande également de lire sur la différence entre les éléments de réaction et les composants

20
Sagiv b.g

En ajoutant à la réponse de sagiv, nous devrions créer le composant parent de manière à ce qu'il puisse contenir tous les composants enfants plutôt que de renvoyer les composants enfants de la manière que vous avez essayé de retourner.

Essayez d'intensifier le composant parent et passez les accessoires à l'intérieur afin que tous les enfants puissent l'utiliser comme ci-dessous

const NewComponent = NewHOC(Movie);

NewHOC est ici le composant parent et tous ses enfants vont utiliser movie comme accessoires. 

Mais de toute façon, vous avez pu résoudre un problème pour les nouveaux développeurs de react, car il pourrait s'agir d'un problème qui pourrait aussi venir et où ils peuvent trouver la solution.

3
Vishal Gupta

Dans mon cas, j'étais un composant de la classe de transport du parent et je l'utilisais comme une variable de propriété, en utilisant TypeScript et Formik, et je fonctionnais bien comme ceci:

Parent 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

export default Parent2 extends React.Component{
  render(){
    const { componentToFormik } = this.props
    return(
    <Formik 
      render={(formikProps) => {
        return(
          <React.fragment>
            {(new componentToFormik(formikProps)).render()}
          </React.fragment>
        )
      }}
    />
    )
  }
}