web-dev-qa-db-ja.com

関数は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>
    }
}

私は何を間違えていますか?

36
learner

通常のコンポーネントとして使用していますが、実際にはコンポーネントを返す関数です。

次のようなことを試してください:

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については docs で読むことができ、 反応する要素とコンポーネントの違い についても読むことをお勧めします。

32
Sagiv b.g

私の場合、反応するコンポーネントのレンダリング関数内の関数名の後に()を追加するのを忘れました

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

       return ctrl;
    };


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

エラーメッセージに記載されているように、renderメソッドを変更する

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

問題を修正しました

4
Stefan Michev

Sagivの答えに加えて、子コンポーネントを返そうとした方法で返すのではなく、すべての子コンポーネントで構成されるように親コンポーネントを作成する必要があります。

親コンポーネントを意図し、その中に小道具を渡して、すべての子供が以下のように使用できるようにします

const NewComponent = NewHOC(Movie);

ここで、NewHOCは親コンポーネントであり、そのすべての子はムービーを小道具として使用します。

しかし、とにかく、あなたは新しいリアクション開発者の問題を解決しました。これは、これもまた起こりうる問題であり、ここで彼らがその解決策を見つけることができる場所です。

3
Vishal Gupta

私の場合、私は親からトランスポートクラスコンポーネントであり、TypeScriptとFormikを使用して、内部でprop変数として使用し、次のように実行します。

親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>
        )
      }}
    />
    )
  }
}