Muitas linguagens de modelos possuem instruções "slots" ou "yield", que permitem fazer algum tipo de inversão de controle para agrupar um modelo dentro de outro.
Angular possui a opção "transcluir" .
Rails possui declaração de rendimento . Se o React.js tivesse uma declaração de rendimento, seria assim:
var Wrapper = React.createClass({
render: function() {
return (
<div className="wrapper">
before
<yield/>
after
</div>
);
}
});
var Main = React.createClass({
render: function() {
return (
<Wrapper><h1>content</h1></Wrapper>
);
}
});
Saída desejada:
<div class="wrapper">
before
<h1>content</h1>
after
</div>
Infelizmente, React.js não tem um <yield/>
. Como defino o componente Wrapper para obter a mesma saída?
Respostas:
Experimentar:
Consulte Acessórios múltiplos: filhos e tipo de filhos nos documentos para obter mais informações.
fonte
Usando
children
Isso também é conhecido como
transclusion
em Angular.children
é um suporte especial no React e conterá o que está dentro das tags do seu componente (aqui<App name={name}/>
está dentroWrapper
, então é ochildren
Observe que você não precisa necessariamente usar
children
, que é exclusivo para um componente, e também pode usar adereços normais, se desejar, ou misturar adereços e filhos:Isso é simples e adequado para muitos casos de uso, e eu recomendo isso para a maioria dos aplicativos de consumo.
render adereços
É possível passar funções de renderização para um componente, esse padrão é geralmente chamado
render prop
e ochildren
prop é frequentemente usado para fornecer esse retorno de chamada.Esse padrão não é realmente destinado ao layout. O componente wrapper geralmente é usado para manter e gerenciar algum estado e injetá-lo em suas funções de renderização.
Exemplo de contador:
Você pode ficar ainda mais sofisticado e até fornecer um objeto
Observe que você não precisa necessariamente usar
children
, é uma questão de gosto / API.Atualmente, muitas bibliotecas estão usando objetos de renderização (contexto de reação, movimento de reação, Apollo ...) porque as pessoas tendem a achar essa API mais fácil do que as HOCs. O react-powerplug é uma coleção de componentes simples de render-prop. reagir-adotar ajuda na composição.
Componentes de ordem superior (HOC).
Um componente de ordem superior / HOC geralmente é uma função que pega um componente e retorna um novo componente.
O uso de um componente de ordem superior pode ter mais desempenho do que o uso
children
ourender props
, porque o wrapper pode ter a capacidade de causar um curto-circuito na renderização um passo à frenteshouldComponentUpdate
.Aqui estamos usando
PureComponent
. Ao renderizar novamente o aplicativo, se oWrappedApp
nome prop não for alterado com o tempo, o wrapper poderá dizer "Não preciso renderizar porque os props (na verdade, o nome) são os mesmos de antes". Com achildren
solução baseada acima, mesmo que o wrapper sejaPureComponent
, não é o caso, porque o elemento filho é recriado toda vez que o pai é renderizado, o que significa que o wrapper provavelmente sempre será renderizado novamente, mesmo que o componente embrulhado seja puro. Existe um plugin babel que pode ajudar a mitigar isso e garantir umchildren
elemento constante ao longo do tempo.Conclusão
Componentes de ordem superior podem oferecer melhor desempenho. Não é tão complicado, mas certamente parece hostil no começo.
Não migre toda a sua base de código para o HOC depois de ler isso. Lembre-se de que nos caminhos críticos do seu aplicativo você pode usar HOCs em vez de wrappers de tempo de execução por motivos de desempenho, principalmente se o mesmo wrapper for usado várias vezes, vale a pena considerar torná-lo um HOC.
O Redux usou inicialmente um wrapper de tempo de execução
<Connect>
e depois mudou para um HOCconnect(options)(Comp)
por motivos de desempenho (por padrão, o wrapper é puro e usadoshouldComponentUpdate
). Esta é a ilustração perfeita do que eu queria destacar nesta resposta.Observe que, se um componente possui uma API de renderização, geralmente é fácil criar um HOC sobre ela; portanto, se você é um autor da lib, deve primeiro criar uma API de renderização e, eventualmente, oferecer uma versão HOC. É isso que a Apollo faz com o
<Query>
componente render-prop e ographql
HOC usando-o.Pessoalmente, uso os dois, mas em caso de dúvida prefiro HOCs porque:
compose(hoc1,hoc2)(Comp)
) em comparação com renderizaçõesNão hesito em usar / criar versões HOC das minhas ferramentas favoritas:
Context.Consumer
compSubscribe
graphql
HOC da Apollo em vez deQuery
render propNa minha opinião, às vezes os objetos de renderização tornam o código mais legível, às vezes menos ... Eu tento usar a solução mais pragmática de acordo com as restrições que tenho. Às vezes, a legibilidade é mais importante que as performances, às vezes não. Escolha sabiamente e não siga a tendência de 2018 de converter tudo em adereços de renderização.
fonte
Além da resposta de Sophie, também achei útil enviar tipos de componentes filhos, fazendo algo assim:
fonte
delegate
, como você a encontrou?