Moim celem jest dynamiczne dodawanie komponentów do strony / komponentu nadrzędnego.
Zacząłem od podstawowego przykładowego szablonu, takiego jak ten:
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>
);
}
});
Tutaj SampleComponent
jest zamontowany do <div id="myId"></div>
węzła, który jest wstępnie zapisany w App.js
szablonie. Ale co, jeśli muszę dodać nieokreśloną liczbę składników do składnika aplikacji? Oczywiście nie mogę mieć wszystkich wymaganych elementów div .
Po przeczytaniu kilku samouczków nadal nie rozumiem, w jaki sposób komponenty są tworzone i dynamicznie dodawane do komponentu macierzystego. Jak to zrobić?
javascript
reactjs
babeljs
Justin Trevein
źródło
źródło
ReactDOM.render
raz, a wszystkie inne komponenty są elementamiOdpowiedzi:
Musisz przekazać swoje komponenty jako dzieci, na przykład:
var App = require('./App.js'); var SampleComponent = require('./SampleComponent.js'); ReactDOM.render( <App> <SampleComponent name="SomeName"/> <App>, document.body );
A następnie dołącz je do treści komponentu:
var App = React.createClass({ render: function() { return ( <div> <h1>App main component! </h1> { this.props.children } </div> ); } });
Nie musisz ręcznie manipulować kodem HTML, React zrobi to za Ciebie. Jeśli chcesz dodać jakieś komponenty potomne, wystarczy zmienić właściwości lub stan, w którym to zależy. Na przykład:
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> ); } });
źródło
Po pierwsze, nie użyłbym document.body . Zamiast tego dodaj pusty pojemnik:
index.html:
<html> <head></head> <body> <div id="app"></div> </body> </html>
Następnie zdecyduj się renderować tylko swój
<App />
element:main.js:
var App = require('./App.js'); ReactDOM.render(<App />, document.getElementById('app'));
Wewnątrz
App.js
możesz zaimportować inne komponenty i całkowicie zignorować kod renderujący 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> ); } });
Następnie można programowo współdziałać z dowolną liczbą komponentów, importując je do niezbędnych plików komponentów za pomocą
require
.źródło
Udostępniam tutaj moje rozwiązanie na podstawie odpowiedzi Chrisa. Mam nadzieję, że może pomóc innym.
Musiałem dynamicznie dołączyć elementy podrzędne do mojego JSX, ale w prostszy sposób niż warunkowe sprawdzenia w mojej instrukcji return. Chcę pokazać program ładujący w przypadku, gdy elementy potomne nie są jeszcze gotowe. Oto ona:
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> ) }
Teraz zdaję sobie sprawę, że mógłbym po prostu umieścić
{pushMessages}
i{emailMessages}
bezpośrednio w moimreturn()
poniżej, ale zakładając, że mam jeszcze więcej warunkowej zawartości,return()
wyglądałbym po prostu na zagracony.źródło
Po pierwsze ostrzeżenie: nigdy nie powinieneś majstrować przy DOM zarządzanym przez React, który robisz dzwoniąc
ReactDOM.render(<SampleComponent ... />);
Z Reactem powinieneś używać SampleComponent bezpośrednio w głównej aplikacji.
var App = require('./App.js'); var SampleComponent = require('./SampleComponent.js'); ReactDOM.render(<App/>, document.body);
Zawartość twojego komponentu nie ma znaczenia, ale powinna być używana w następujący sposób:
var App = React.createClass({ render: function() { return ( <div> <h1>App main component! </h1> <SampleComponent name="SomeName"/> </div> ); } });
Następnie możesz rozszerzyć składnik aplikacji, aby używał listy.
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> ); } });
Naprawdę poleciłbym przejrzenie dokumentacji Reacta, a następnie wykonanie instrukcji „Rozpocznij”. Czas, który na to poświęcisz, opłaci się później.
https://facebook.github.io/react/index.html
źródło
SampleComponent
s, co w związku z tym nie wymaga mapowania. Gdyby lista była listą nazwisk, wymagałaby odwzorowania na komponenty Reacta.<div>
przypisanym do zmiennej, która została następnie wstawiona do JSX, jak{content}
w mojej instrukcji return. Korzystanie z pustej tablicy było takie proste!