En Guide till Egna Element för att Reagera Utvecklare

0
9

Jag var tvungen att bygga en UI nyligen och (för första gången på länge) som jag inte har möjlighet att använda React.js som är min bästa lösningen för UI dessa dagar. Så, jag tittade på vad den inbyggda webbläsaren Api: er hade att erbjuda och såg att använda anpassade element (aka Web Components) kan bara vara den rätta att denna Reagerar utvecklare som behövs.

Anpassade element kan erbjuda samma allmänna fördelarna med att Reagera komponenter utan att vara bunden till en specifik ram för genomförandet. Ett anpassat element ger oss en ny HTML-tag som vi kan programmässigt kontroll genom en egenutvecklad webbläsare API.

Låt oss tala om fördelarna med en komponentbaserad UI:

  • Inkapsling – oro begränsad till att komponenten kvar i den del av genomförandet
  • Återanvändning – när UI är separerade i mer generiska delar, de är lättare att bryta sig in i mönster som du är mer benägna att upprepa
  • Isolering – eftersom komponenterna är utformade för att vara inkapslade och med att du får den extra fördelen av isolering, vilket gör att du omfattning fel och ändringar till en viss del av din ansökan lättare

Använd fall

Du kanske undrar vem det är som använder anpassade element i produktionen. Särskilt:

  • GitHub är att använda egna element för deras modala dialoger, komplettera automatiskt och visar tiden.
  • YouTube ‘ s nya web app är byggd med Polymer och web components.

Likheter med den Komponent API

När man försöker att jämföra Reagera Komponenter jämfört med anpassade element, jag hittade de Api: er som verkligen liknar:

  • De är båda klasser som inte är “nya” och har möjlighet att förlänga en basklass
  • De båda ärver en montering eller göra lifecycle
  • De båda tar statisk eller dynamisk ingång via rekvisita eller attribut

Demo

Så, låt oss bygga upp en litet program som visar information om ett GitHub repository.

Om jag var på väg att närma sig det här med att Reagera, jag skulle definiera en enkel komponent som den här:

<Arkivnamn=”charliewilco/obsidian” />

Denna komponent tar ett enda prop namn, arkiv — och vi genomföra det så här:

klass Arkivet sträcker sig Reagera.Komponent {
state = {
repo: null
};

async getDetails(namn) {
retur väntar hämta(`https://api.github.com/repos/${name}`, {
läge: ‘co’
}).då(res => res.json());
}

async componentDidMount() {
const { name } = i detta.rekvisita;
const repo = väntar på detta.getDetails(namn);
detta.setState({ repo });
}

render() {
const { repo } = i detta.stat.

if (!repo) {
återgå <h1>Lastning</h1>;
}

om (repo.message) {
återgå <div className=”Kortet Kortet–error”>Fel: {repo.meddelande}</div>;
}

avkastning (
<div class=”Card”>
<bortsett>
<img
width=”48″
height=”48″
class=”Avatar”
src={repo.ägare.avatar_url}
alt=”profilbild för ${repo.ägare.logga in}”
/>
</aside>
<header>
<h2 class=”Card__title”>{repo.full_name}</h2>
<span class=”Card__meta”>{repo.beskrivning}</span>
</header>
</div>
);
}
}

Se Pennan Reagera Demo – GitHub av Charles (@charliewilco) på CodePen.

Att bryta ned det ytterligare, vi har en komponent som har sin egen stat, som är den mörkblå detaljer. Först satte vi den vara noll eftersom vi inte har någon data ännu, så vi kommer att ha en laddning indikator samtidigt som data hämtas.

Under Reagera livscykel, vi kommer att använda hämta för att gå och hämta data från GitHub, ställa upp kortet, och utlösa ett nytt göra med setState() efter att vi få tillbaka data. Alla dessa olika stater UI tar är representerade i render () – metoden.

Definiera / med Hjälp av ett Anpassat Element

Gör detta med egna element är lite annorlunda. Som Reagerar komponent, vår egen del kommer att ta ett enda attribut — igen, namnet på arkivet och hantera sin egen stat.

Vårt inslag kommer att se ut så här:

<github-repo namn=”charliewilco/obsidian”></github-repo>
<github-repo namn=”charliewilco/nivå.css”></github-repo>
<github-repo namn=”charliewilco/reagera-grenar”></github-repo>
<github-repo namn=”charliewilco/reagera-gluejar”></github-repo>
<github-repo namn=”charliewilco/dotfiles”></github-repo>

Se Pennan Anpassade Element Demo – GitHub av Charles (@charliewilco) på CodePen.

För att börja, allt vi behöver göra för att definiera och registrera en egen del är att skapa en klass som utökar HTMLElement klass och sedan registrera namnet på elementet med customElements.define().

klass OurCustomElement sträcker sig HTMLElement {}
fönster.customElements.define(‘vår-element’, OurCustomElement);

Och vi kan kalla det:

<vår-element></element>

Detta nya element är inte särskilt användbar, men med egna element, vi får tre metoder för att utöka funktionaliteten i denna del. Dessa är nästan jämförbart med att Reagera livscykel metoder för deras Komponent i API. De två lifecycle-liknande metoder som är mest relevanta för oss är disconnectedCallBack och connectedCallback och eftersom detta är en klass, det kommer med en konstruktör.

Namn
Anropas när

konstruktör Ett exempel på element är skapad eller uppgraderas. Användbart för att initiera staten, inställningar upp händelsen lyssnare, eller skapa Skugga DOM. Se spec för begränsningar på vad du kan göra i konstruktorn.
connectedCallback Element sätts in DOM. Användbart för att köra setup-koden, som hämtar resurser eller göra ANVÄNDARGRÄNSSNITTET. I allmänhet bör du försöka fördröja arbetet fram till denna tid
disconnectedCallback När den delen tas bort från DOM. Användbart för att köra clean-up koden.

För att genomföra vår egen del, vi ska skapa klass och ställa upp några egenskaper som är relaterade till att UI:

klass Arkivet sträcker sig HTMLElement {
konstruktör() {
super();

detta.repoDetails = null;

detta.namn = detta.getAttribute(“namn”);
detta.endpoint = `https://api.github.com/repos/${detta.namn}`
detta.innerHTML = `<h1>Lastning</h1>`
}
}

Genom att ringa super() i vår konstruktör samband med detta är element i sig och alla DOM manipulation Api: er kan användas. Så långt har vi satt den standard arkivet detaljer null, fått repo namn från elementets attribut, skapat en slutpunkt för att ringa så att vi inte behöver definiera det senare och, viktigast av allt, den ursprungliga HTML-att vara en belastning indikator.

För att få information om att delar av arkivet, som vi kommer att behöva göra en begäran till GitHub: s API. Vi kommer att använda hämta och eftersom Löfte-baserade, vi kommer att använda asynkron och väntar på att göra vår kod mer lättläst. Du kan lära dig mer om async/väntar sökord här och mer om för webbläsaren att hämta API här. Du kan också twittra på mig att ta reda på om jag föredrar det till Axios bibliotek. (Tips, det beror på om jag hade te eller kaffe med min frukost.)

Låt oss nu lägga till en metod för att denna klass för att be GitHub för mer information om arkivet.

klass Arkivet sträcker sig HTMLElement {
konstruktör() {
// …
}

async getDetails() {
retur väntar på hämta(för detta.endpoint, {- läge: “cors” }).då(res => res.json());
}
}

Nästa, låt oss använda den connectedCallback metod och Skuggan DOM att använda returvärdet från denna metod. Med hjälp av denna metod kommer att göra något liknande som när vi ringde Arkiv.componentDidMount() i den Reagerar exempel. Istället, vi kommer att åsidosätta null vi till en början gav detta.repoDetails — vi kommer att använda denna senare när vi börja kalla mallen för att skapa HTML.

klass Arkivet sträcker sig HTMLElement {
konstruktör() {
// …
}

async getDetails() {
// …
}

async connectedCallback() {
låt repo = väntar på detta.getDetails();
detta.repoDetails = repo;
detta.initShadowDOM();
}

initShadowDOM() {
låt shadowRoot = detta.attachShadow({ mode: “öppna” });
shadowRoot.innerHTML = detta.mallen.
}
}

Du kommer att märka att vi ringer metoder relaterade till Skuggan DOM. Förutom att vara en avvisas titel för en Marvel film, Skuggan DOM har sin egen rika API värt att titta in. För våra syften, men det kommer att abstrakt genomförandet för att lägga till innerHTML till elementet.

Nu är vi tilldela innerHTML att vara lika med värdet av detta.mall. Låt oss definiera det nu:

klass Arkivet sträcker sig HTMLElement {
få mallen() {
const repo = detta.repoDetails;

// om vi får ett felmeddelande låt oss visa det tillbaka till användaren
om (repo.message) {
return `<div class=”card Kort–error”>Fel: ${repo.meddelande}</div>`
} else {
tillbaka”
<div class=”Card”>
<bortsett>
<img width=”48″ height=”48″ height=”Avatar” src=”${repo.ägare.avatar_url}” alt=”profilbild för ${repo.ägare.logga in}” />
</aside>
<header>
<h2 class=”Card__title”>${repo.full_name}</h2>
<span class=”Card__meta”>${repo.beskrivning}</span>
</header>
</div>
`
}
}
}

Det är ganska mycket det. Vi har definierat ett anpassat element som hanterar sin egen stat, hämtar sin egen data, och är ett uttryck för att staten tillbaka till användaren, samtidigt som det ger oss ett HTML-element att använda i vår ansökan.

Efter att ha gått igenom denna övning, fann jag att det enda som krävs beroende för egna element är webbläsarens native-Api: er snarare än en ram för att dessutom tolka och köra. Detta ger en mer portabel och återanvändbara lösning med liknande Api: er till de ramar som du redan älskar och använda för att göra ditt boende.

Det finns nackdelar med att använda detta tillvägagångssätt, naturligtvis. Vi pratar om olika webbläsare stöd för frågor, och en viss brist på konsekvens. Plus, att arbeta med DOM manipulation Api: er kan vara mycket förvirrande. Ibland är de uppdrag. Ibland de fungerar. Ibland är dessa funktioner tar en callback och ibland inte. Om du inte tror mig, ta en titt på att lägga till en klass till ett HTML-element som har skapats via dokument.createElement(), som är en av de top fem skäl att använda Reagera. Grundläggande genomförandet är inte så komplicerat men det är inkonsekvent med andra liknande metoder.

Den verkliga frågan är: spelar det ens ut i tvätten? Kanske. Reagera är fortfarande ganska bra på det den är designad för att vara väldigt bra på att: den virtuella DOM, hantera ansökan staten, inkapsling, och går ner trädet. Det finns nästa inga incitament för att använda anpassade element inuti ramen. Egna element, å andra sidan, är enkelt tillgänglig genom att bygga ett program för webbläsaren.

Läs mer

  • Anpassade Element v1: Återanvändbara Komponenter Webben
  • Gör en Infödd Web Component med Egna Element v1 och Skugga DOM v1

Jetpack WordPress plugin som körs på denna webbplats, driver inte bara relaterade inlägg nedan, men den sociala dela länkar ovan, säkerhet och backup, Wiki-stöd, sök på sajten, kommentera form, sättande till sociala nätverk, och mycket mer!