web-dev-qa-db-ja.com

React JSでのコンポーネント間の切り替え

2つのコンポーネントからなる単純なフローを作成したいと思います。最初のコンポーネントがレンダリングされます。ボタンをクリックすると、このアクションによって2番目のコンポーネントがレンダリングされます。 2番目のコンポーネントのボタンをクリックすると、最初のコンポーネントに戻るはずですが、代わりにエラーが発生しました。

警告:React.createElement:typeは、null、undefined、boolean、またはnumberであってはなりません。文字列(DOM要素の場合)またはReactClass(複合コンポーネントの場合)である必要があります。 exports。warning @ react.js:20728ReactElementValidator.createElement @ react.js:9853t.exports.React.createClass.render @ bundle.js:1ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext @ react.js:6330ReactCompositeComponentMixinのrenderメソッドを確認します。 _renderValidatedComponent @ react.js:6350wrapper @ react.js:12868ReactCompositeComponentMixin._updateRenderedComponent @ react.js:6303ReactCompositeComponentMixin._performComponentUpdate @ react.js:6287ReactCompositeComponentMixin.updateComponent @ react.js:6216wrapper @ react.js:12868Re 6164ReactReconciler.performUpdateIfNecessary @ react.js:13667runBatchedUpdates @ react.js:15356Mixin.perform @ react.js:17245Mixin.perform @ react.js:17245assign.perform @ react.js:15313flushBatchedUpdates @ react.js:15374wrapper @ react.js: 12868Mixin.closeAll @ react.js:17311Mixin.perform @ react.js:17258ReactDefaultBatchingStrategy.batchedUpdates @ react.js:8842batc hedUpdates @ react.js:15321ReactEventListener.dispatchEvent @ react.js:10336 react.js:20250

キャッチされないエラー:不変の違反:要素タイプが無効です:文字列(組み込みコンポーネントの場合)またはクラス/関数(複合コンポーネントの場合)が必要ですが、オブジェクトを取得しました。 exports。invariant @ react.js:20250instantiateReactComponent @ react.js:18268ReactCompositeComponentMixin._updateRenderedComponent @ react.js:6312ReactCompositeComponentMixin._performComponentUpdate @ react.js:6287ReactCompositeComponentMixin.updateComponent @ react.jsのrenderメソッドを確認しますreact.js:12868ReactCompositeComponentMixin.performUpdateIfNecessary @ react.js:6164ReactReconciler.performUpdateIfNecessary @ react.js:13667runBatchedUpdates @ react.js:15356Mixin.perform @ react.js:17245Mixin.perform @ react.js:17245assign.perform 15313flushBatchedUpdates @ react.js:15374wrapper @ react.js:12868Mixin.closeAll @ react.js:17311Mixin.perform @ react.js:17258ReactDefaultBatchingStrategy.batchedUpdates @ react.js:8842batchedUpdates @ react.js:15321ReactEventListener.dispatchEvent @ react.js: 10336

最初のコンポーネント:

/** @jsx React.DOM */

var Second = require('components/second/view.jsx');

module.exports = React.createClass({

handlerClick: function () {
    ReactDOM.render(
        <Second />,
        document.getElementById("app-container")
    )
},

render: function() {
  return (
    <input type="button" value="COMPONENT 1" onClick={this.handlerClick} />
  )
}
});

2番目のコンポーネント:

/** @jsx React.DOM */

var First = require('components/first/view.jsx');

module.exports = React.createClass({

handlerClick: function () {
    ReactDOM.render(
        <First />,
        document.getElementById("app-container")
    )
},

render: function() {
  return (
    <input type="button" value="COMPONENT 2" onClick={this.handlerClick} />
  )
}
});

Index.js

ReactDOM.render(
    <div>
        <First />
    </div>,
    document.getElementById("app-container")
);
6
user5512965

アプリケーションをマウントするときにのみ、ReactDOM.render()を呼び出します。一度マウントすると、同じマウントポイントでReactDOM.render()を再度呼び出すことはありません。 [*以下の更新を参照してください。]

あなたの見解はあなたの小道具と状態の関数であることを忘れないでください。ビューを変更するには、状態の変更をトリガーします。

私はこのようなものを提案します:

_var Parent = React.createClass({

    getInitialState: function () {
        return {
            active: 'FIRST'
        };
    },

    handleClick: function () {
        var active = this.state.active;
        var newActive = active === 'FIRST' ? 'SECOND' : 'FIRST';
        this.setState({
            active: newActive
        });
    },

    render: function () {

        var active = this.state.active;

        return (
            <div>
                {active === 'FIRST' ? (
                    <First />
                ) : active === 'SECOND' ? (
                    <Second />
                ) : null}
                <button type="button" onClick={this.handleClick}>
                    Toggle
                </button>
            </div>
        );

     }

});
_

そして、親をルートノードにします。つまり.

_ReactDOM.render(<Parent />, document.getElementById('app-container'));
_

UPDATE:それ以来私はあなたを学んだcancall ReactDOM.render()同じマウントポイントで複数回 。これは通常、アプリケーションを初期化するのと同じ場所にあります。それでも、Reactコンポーネントの内部からReactDOM.render()を呼び出さないでください。

8
David L. Walsh

レンダリング関数では、三項演算子は単純に置き換えられ、完全な答えは次のようになります。

    /** @jsx React.DOM */

    var Parent = React.createClass({
    getInitialState: function () {
        return {
            active: 'FIRST'
        };
    },

        handleClick: function () {
            var active = this.state.active;
            var newActive = active === 'FIRST' ? 'SECOND' : 'FIRST';
            this.setState({
                active: newActive
            });
        },

        render: function () {

            var active = this.state.active;

            return (
                <div>
                    {(active === 'FIRST') && <First /> }
                    {(active === 'SECOND') && <Second /> }
                    <button type="button" onClick={this.handleClick}>
                        Toggle
                    </button>
                </div>
            );

         }
    });


  ReactDOM.render(<Parent />, document.getElementById('app-container'));

残りは同じになります。

1
DilipCoder

フックバージョン(React 16.8+):

最小バージョン。

import React, { useState } from 'react';

export default function App() {
  const [toggle, setToggle] = useState(true);
  const toggleChecked = () => setToggle(toggle => !toggle);
  return (
     <div>
        {toggle && <First /> }
        {!toggle && <Second /> }
        <button type="button" onClick={this.toggleChecked}>
           Toggle
        </button>
     </div>
  );
}
0
Hunter