Mi objetivo es agregar componentes dinámicamente en una página / componente principal.
Comencé con una plantilla de ejemplo básica como esta:
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>
);
}
});
Aquí SampleComponent
está montado en el <div id="myId"></div>
nodo, que está escrito previamente en la App.js
plantilla. Pero, ¿qué sucede si necesito agregar un número indefinido de componentes al componente de la aplicación? Obviamente, no puedo tener todos los divs requeridos allí.
Después de leer algunos tutoriales, todavía no entiendo cómo se crean y agregan los componentes al componente principal de forma dinámica. ¿Cuál es una forma de hacerlo?
javascript
reactjs
babeljs
Justin Trevein
fuente
fuente
ReactDOM.render
una vez y todos los demás componentes son hijos del nodo 'raíz'Respuestas:
Debes pasar tus componentes como hijos, así:
var App = require('./App.js'); var SampleComponent = require('./SampleComponent.js'); ReactDOM.render( <App> <SampleComponent name="SomeName"/> <App>, document.body );
Y luego añádalos en el cuerpo del componente:
var App = React.createClass({ render: function() { return ( <div> <h1>App main component! </h1> { this.props.children } </div> ); } });
No necesita manipular manualmente el código HTML, React lo hará por usted. Si desea agregar algunos componentes secundarios, solo necesita cambiar los accesorios o indicar que depende. Por ejemplo:
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> ); } });
fuente
Primero, no usaría document.body . En su lugar, agregue un contenedor vacío:
index.html:
<html> <head></head> <body> <div id="app"></div> </body> </html>
Entonces opte por renderizar solo su
<App />
elemento:main.js:
var App = require('./App.js'); ReactDOM.render(<App />, document.getElementById('app'));
Dentro de
App.js
usted puede importar sus otros componentes e ignorar su código de renderizado DOM por completo: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> ); } });
Luego, puede interactuar mediante programación con cualquier número de componentes importándolos en los archivos de componentes necesarios usando
require
.fuente
Comparto mi solución aquí, basada en la respuesta de Chris. Espero que pueda ayudar a otros.
Necesitaba agregar dinámicamente elementos secundarios a mi JSX, pero de una manera más simple que las verificaciones condicionales en mi declaración de devolución. Quiero mostrar un cargador en el caso de que los elementos secundarios aún no estén listos. Aquí está:
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> ) }
Ahora, me doy cuenta de que también podría poner
{pushMessages}
y{emailMessages}
directamente en mi partereturn()
inferior, pero suponiendo que tuviera aún más contenido condicional, mireturn()
se vería desordenado.fuente
En primer lugar, una advertencia: nunca debe jugar con DOM administrado por React, lo que está haciendo llamando
ReactDOM.render(<SampleComponent ... />);
Con React, debe usar SampleComponent directamente en la aplicación principal.
var App = require('./App.js'); var SampleComponent = require('./SampleComponent.js'); ReactDOM.render(<App/>, document.body);
El contenido de su componente es irrelevante, pero debe usarse así:
var App = React.createClass({ render: function() { return ( <div> <h1>App main component! </h1> <SampleComponent name="SomeName"/> </div> ); } });
Luego, puede extender el componente de su aplicación para usar una lista.
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> ); } });
Realmente recomendaría que mire la documentación de React y luego siga las instrucciones de "Comenzar". El tiempo que le dedique se verá recompensado más tarde.
https://facebook.github.io/react/index.html
fuente
SampleComponent
s, por lo que no requiere un mapeo. Si la lista fuera una lista de nombres, entonces requeriría una asignación a los componentes de React.<div>
asignado a una variable que luego se insertó en JSX como{content}
en mi declaración de devolución. ¡Usar una matriz vacía fue tan fácil!