Meu objetivo é adicionar componentes dinamicamente em um componente de página / pai.
Comecei com um modelo básico de exemplo como este:
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>
);
}
});
Aqui SampleComponent
está montado no <div id="myId"></div>
nó, que é pré-escrito no App.js
modelo. Mas e se eu precisar adicionar um número indefinido de componentes ao componente do aplicativo? Obviamente, não posso ter todos os divs exigidos ali.
Depois de ler alguns tutoriais, ainda não entendi como os componentes são criados e adicionados ao componente pai dinamicamente. Qual é a maneira de fazer isso?
javascript
reactjs
babeljs
Justin Trevein
fonte
fonte
ReactDOM.render
uma vez e todos os outros componentes são filhos do nó 'raiz'Respostas:
Você precisa passar seus componentes como filhos, assim:
var App = require('./App.js'); var SampleComponent = require('./SampleComponent.js'); ReactDOM.render( <App> <SampleComponent name="SomeName"/> <App>, document.body );
E, em seguida, anexe-os ao corpo do componente:
var App = React.createClass({ render: function() { return ( <div> <h1>App main component! </h1> { this.props.children } </div> ); } });
Você não precisa manipular manualmente o código HTML, o React fará isso por você. Se você quiser adicionar alguns componentes filhos, você só precisa alterar os adereços ou definir que depende. Por exemplo:
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> ); } });
fonte
Primeiro, eu não usaria document.body . Em vez disso, adicione um contêiner vazio:
index.html:
<html> <head></head> <body> <div id="app"></div> </body> </html>
Em seguida, opte por renderizar apenas o seu
<App />
elemento:main.js:
var App = require('./App.js'); ReactDOM.render(<App />, document.getElementById('app'));
Dentro,
App.js
você pode importar seus outros componentes e ignorar completamente o código de renderização 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> ); } });
Em seguida, você pode interagir programaticamente com qualquer número de componentes, importando-os para os arquivos de componentes necessários usando
require
.fonte
Compartilhando minha solução aqui, com base na resposta de Chris. Espero que possa ajudar outras pessoas.
Eu precisava anexar dinamicamente elementos filho em meu JSX, mas de uma maneira mais simples do que verificações condicionais em minha instrução de retorno. Quero mostrar um carregador no caso de os elementos filhos ainda não estarem prontos. Aqui 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> ) }
Agora, eu percebo que também poderia colocar
{pushMessages}
e{emailMessages}
diretamente no meureturn()
abaixo, mas supondo que eu tivesse ainda mais conteúdo condicional, o meureturn()
pareceria desordenado.fonte
Em primeiro lugar, um aviso: você nunca deve mexer no DOM gerenciado pelo React, o que você está fazendo chamando
ReactDOM.render(<SampleComponent ... />);
Com o React, você deve usar SampleComponent diretamente no aplicativo principal.
var App = require('./App.js'); var SampleComponent = require('./SampleComponent.js'); ReactDOM.render(<App/>, document.body);
O conteúdo do seu componente é irrelevante, mas deve ser usado assim:
var App = React.createClass({ render: function() { return ( <div> <h1>App main component! </h1> <SampleComponent name="SomeName"/> </div> ); } });
Você pode então estender o componente do seu aplicativo para usar uma 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> ); } });
Eu realmente recomendo que você leia a documentação do React e siga as instruções de "Primeiros passos". O tempo que você gasta nisso terá retorno mais tarde.
https://facebook.github.io/react/index.html
fonte
SampleComponent
s, o que, portanto, não requer um mapeamento. Se a lista fosse uma lista de nomes, seria necessário um mapeamento para os componentes do React.<div>
atribuído a uma variável que foi então inserida em JSX como{content}
em minha instrução de retorno. Usar um array vazio foi tão fácil!