Como usar o reatividade.createPortal () em React 16?
estou a usar o React 16 e preciso de portais, mas não consigo encontrar qualquer documentação sobre este recurso. Alguém já sabe como usar isto?
Obrigado por qualquer conselho.2 answers
Portal
.
O Que é Portal? Há quanto tempo está lá?
Os portais fornecem uma forma de primeira classe para transformar crianças num nó DOM que existe fora da hierarquia DOM do componente-mãe.
Portal
não é um conceito novo na comunidade react. Muitas bibliotecas estão disponíveis que suportam este tipo de funcionalidade. p. ex. react-portal and react-gateway.
O que acontece ao renderizar qualquer aplicativo reat?
Geralmente, ao renderizar qualquer aplicação React, um único elemento DOM é usado para renderizar toda a árvore React.
class HelloReact extends React.Component {
render() {
return (
<h1>Hello React</h1>
);
}
}
ReactDOM.render(<HelloReact />, document.getElementById('root'));
Como podem ver, estamos a transformar o nosso componente react num elemento DOM com id root
.
O Que é Portal e por que é necessário? Porque está lá?
Os portais são uma forma de fazer com que as crianças reajam lá fora. a principal hierarquia DOM do componente-mãesem perder o contexto de reacção. Estou enfatizando isso porque bibliotecas muito populares como reat-router, O redux usa fortemente o contexto de reacção. Assim, a disponibilidade de contexto ao usarPortal
é muito útil.
De acordo com o reaja docs,
Um caso típico de uso para portais é quando um componente-mãe tem um excesso: escondido ou estilo de índice-z, mas você precisa que o filho visualmente "partir" do seu recipiente. Por exemplo, dialogs, hovercards e tooltip.
Então, com portais, você pode desenhar uma árvore de reação paralela em outro nó DOM quando necessário. Mesmo que seja renderizado no nó DOM diferente, o componente pai pode pegar os eventos não declarados. Ver este codepen fornecido nos próprios documentos.
O exemplo abaixo deve dar mais ideia:
// index.html
<html>
<body>
<div id="root"></div>
<div id="another-root"></div>
</body>
</html>
// index.jsx
const mainContainer = document.getElementById('root');
const portalContainer = document.getElementById('another-root');
class HelloFromPortal extends React.Component {
render() {
return (
<h1>I am rendered through a Portal.</h1>
);
}
}
class HelloReact extends React.Component {
render() {
return (
<div>
<h1>Hello World</h1>
{ ReactDOM.createPortal(<HelloFromPortal />, portalContainer) }
</div>
);
}
}
ReactDOM.render(<HelloReact />, mainContainer);
Https://codesandbox.io/s/62rvxkonnw
Pode usar o elemento devtools inspeccionar e ver que <h1>I am rendered through a Portal.</h1>
está representado dentro da marca #another-root
, enquanto <h1>Hello World</h1>
está representado dentro da marca #root
.
Actualizar : para responder ao comentário do @ PhillipMunin .
Qual é a diferença entre
ReactDOM.render
eReactDOM.createPortal
?
Mesmo que o componente renderizado através do portal seja renderizado em algum outro lugar (fora da raiz do recipiente atual), ele permanece presente como o Filho do mesmo componente pai. (Que invocou o
ReactDOM.createPortal
) de modo que quaisquer eventos sobre a criança são propagados para o pai. (Ofc, isso não funciona se você parar manualmente a propagação do evento.)O mesmo contexto é acessível no interior do componente através de um portal. Mas não no caso quando o fazemos directamente.
Os portais são criados chamando o método createPortal
dentro do método render
do seu componente.
render() {
return (
<div>
{ReactDOM.createPortal(this.renderPortal(), this.props.portalEl)}
</div>
)
}
renderPortal
deve devolver o conteúdo para ser renderizado dentro do portal, enquanto portalEl
é um elemento DOM externo que receberá o conteúdo.
Alguém recentemente alterou essa informação sobre Portais pode ser encontrada em testes React .