Моя цель - динамически добавлять компоненты на страницу / родительский компонент.
Я начал с такого базового шаблона:
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
монтируется к <div id="myId"></div>
узлу, который заранее записан в App.js
шаблоне. Но что, если мне нужно добавить неопределенное количество компонентов в компонент приложения? Очевидно, у меня не может быть всех необходимых div .
После прочтения некоторых руководств я все еще не понимаю, как компоненты создаются и добавляются в родительский компонент динамически. Как это сделать?
javascript
reactjs
babeljs
Джастин Тревейн
источник
источник
ReactDOM.render
один раз, а все остальные компоненты являютсяОтветы:
Вам нужно передать свои компоненты как дочерние элементы, например:
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
.источник
Поделюсь своим решением здесь, основываясь на ответе Криса. Надеюсь, это поможет другим.
Мне нужно было динамически добавлять дочерние элементы в мой JSX, но более простым способом, чем условные проверки в моем операторе возврата. Я хочу показать загрузчик в случае, если дочерние элементы еще не готовы. Вот:
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> ) }
Теперь я понимаю, что могу просто вставить
{pushMessages}
и{emailMessages}
прямо вreturn()
нижеследующее, но если предположить, что у меня было еще больше условного контента, мойreturn()
бы просто выглядел загроможденным.источник
Во-первых, предупреждение: вы никогда не должны возиться с DOM, управляемым React, что вы делаете, вызывая
ReactDOM.render(<SampleComponent ... />);
В React вы должны использовать 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, а затем следовать инструкциям «Начало работы». Время, которое вы потратите на это, окупится позже.
https://facebook.github.io/react/index.html
источник
SampleComponent
s, поэтому отображение не требуется. Если бы список был списком имен, то ему потребовалось бы сопоставление с компонентами React.<div>
назначенный переменной, которая затем была вставлена в JSX, как{content}
в моем операторе возврата. Использовать пустой массив было так просто!