私の目標は、ページ/親コンポーネントに動的にコンポーネントを追加することです。
私はこのようないくつかの基本的な例のテンプレートから始めました:
main.js:
var App = require('./App.js');
var SampleComponent = require('./SampleComponent.js');
ReactDOM.render(<App/>, document.body);
ReactDOM.render(<SampleComponent name="SomeName"/>, document.getElementById('myId'));
App.js:
var App = React.createClass({
render: function() {
return (
<div>
<h1>App main component! </h1>
<div id="myId">myId div</div>
</div>
);
}
});
SampleComponent.js:
var SampleComponent = React.createClass({
render: function() {
return (
<div>
<h1>Sample Component! </h1>
</div>
);
}
});
ここで、SampleComponentはApp.jsテンプレートで作成された<div id="myId"></div>
ノードにマウントされています。しかし、Appコンポーネントに無限の数のコンポーネントを追加する必要がある場合はどうなりますか?明らかに、必要なdivすべてをそこに置くことはできません。
いくつかのチュートリアルを読んでも、コンポーネントがどのように作成され、親コンポーネントに動的に追加されるのかについてはまだ理解できません。それを行う方法は何ですか?
このように、コンポーネントを子として渡す必要があります。
var App = require('./App.js');
var SampleComponent = require('./SampleComponent.js');
ReactDOM.render(
<App>
<SampleComponent name="SomeName"/>
<App>,
document.body
);
そしてそれらをコンポーネントの本体に追加します。
var App = React.createClass({
render: function() {
return (
<div>
<h1>App main component! </h1>
{
this.props.children
}
</div>
);
}
});
あなたは手動でHTMLコードを操作する必要はありません、Reactはあなたのためにそれをします。いくつかの子コンポーネントを追加したい場合は、小道具を変更するか、それが依存していると述べる必要があります。例えば:
var App = React.createClass({
getInitialState: function(){
return [
{id:1,name:"Some Name"}
]
},
addChild: function() {
// State change will cause component re-render
this.setState(this.state.concat([
{id:2,name:"Another Name"}
]))
}
render: function() {
return (
<div>
<h1>App main component! </h1>
<button onClick={this.addChild}>Add component</button>
{
this.state.map((item) => (
<SampleComponent key={item.id} name={item.name}/>
))
}
</div>
);
}
});
まず、 私はdocument.bodyは使いません 。代わりに空のコンテナを追加してください。
index.html:
<html>
<head></head>
<body>
<div id="app"></div>
</body>
</html>
それからあなたの<App />
要素だけをレンダリングすることを選びます:
main.js:
var App = require('./App.js');
ReactDOM.render(<App />, document.getElementById('app'));
App.js
内で、他のコンポーネントをインポートして、DOMレンダリングコードを完全に無視することができます。
App.js:
var SampleComponent = require('./SampleComponent.js');
var App = React.createClass({
render: function() {
return (
<div>
<h1>App main component!</h1>
<SampleComponent name="SomeName" />
</div>
);
}
});
SampleComponent.js:
var SampleComponent = React.createClass({
render: function() {
return (
<div>
<h1>Sample Component!</h1>
</div>
);
}
});
その後、require
を使用して必要なコンポーネントファイルにそれらをインポートすることで、プログラムで任意の数のコンポーネントと対話できます。
Chrisの答えに基づいて、ここで私の解決策を共有しましょう。他の人に役立つことを願っています。
私は自分のJSXに動的に子要素を追加する必要がありましたが、私のreturnステートメントの条件付きチェックよりも簡単な方法です。子要素がまだ準備されていない場合のローダーを見せたいです。ここにあります:
export class Settings extends React.PureComponent {
render() {
const loading = (<div>I'm Loading</div>);
let content = [];
let pushMessages = null;
let emailMessages = null;
if (this.props.pushPreferences) {
pushMessages = (<div>Push Content Here</div>);
}
if (this.props.emailPreferences) {
emailMessages = (<div>Email Content Here</div>);
}
// Push the components in the order I want
if (emailMessages) content.Push(emailMessages);
if (pushMessages) content.Push(pushMessages);
return (
<div>
{content.length ? content : loading}
</div>
)
}
さて、以下のreturn()
に直接{pushMessages}
と{emailMessages}
を直接入れることも可能だと思いますが、もっと条件付きのコンテンツがあるとすれば、return()
は雑然としているように見えます。
まず警告です。Reactによって管理されているDOMをいじってはいけません。ReactDOM.render(<SampleComponent ... />);
を呼び出してやっています。
Reactでは、メインのAppで直接SampleComponentを使うべきです。
var App = require('./App.js');
var SampleComponent = require('./SampleComponent.js');
ReactDOM.render(<App/>, document.body);
あなたのコンポーネントの内容は無関係ですが、それはこのように使われるべきです:
var App = React.createClass({
render: function() {
return (
<div>
<h1>App main component! </h1>
<SampleComponent name="SomeName"/>
</div>
);
}
});
その後、リストを使用するようにアプリコンポーネントを拡張できます。
var App = React.createClass({
render: function() {
var componentList = [
<SampleComponent name="SomeName1"/>,
<SampleComponent name="SomeName2"/>
]; // Change this to get the list from props or state
return (
<div>
<h1>App main component! </h1>
{componentList}
</div>
);
}
});
Reactのドキュメントを見てから、「はじめに」の手順に従うことをお勧めします。あなたがそれに費やす時間は後で報われるでしょう。