React er uten tvil det mest populære biblioteket for å bygge interaktive webapplikasjoner. React er imidlertid ikke en fullverdig webramme. Det fokuserer på visningsdelen av den ærverdige MVC-modellen.
Det er et helt React-økosystem som adresserer andre aspekter. I denne opplæringen lærer du om en av de mest grunnleggende elementene i et hvilket som helst webprogram - hvordan du henter data som skal vises. Dette er ikke trivielt. Det finnes flere steder i React-komponenthierarkiet hvor du kan hente data. Når du skal hente data er det en annen bekymring. Du må også vurdere hvilken teknologi du skal bruke for å hente dataene dine og hvor du skal lagre den.
På slutten av denne opplæringen har du et klart bilde av hvordan datainnhenting fungerer i React, fordeler og ulemper med forskjellige tilnærminger, og hvordan du bruker denne kunnskapen til React-applikasjonene dine.
La oss lage et skjelett for vår React-app med create-react-app:
> Reager-data-henter
Resultatet er en ganske utførlig katalogstruktur. Les den utmerkede README-filen hvis du ikke er kjent med create-react-app.
Jeg opprettet en enkel server for lagring og visning av anførselstegn. Det er ikke fokus for denne opplæringen, og dens rolle er å gi et eksternt API for å demonstrere hvordan du henter data med React. Bare for å tilfredsstille din nysgjerrighet, er det et Python 3-program basert på klemmerammen og bruker Redis som vedvarende lagring.
APIen er ekstremt enkel. Det er et enkelt endepunkt, / sitater
. Den returnerer alle de lagrede sitatene som svar på en HTTP GET-forespørsel, og du kan legge til nye sitater ved å sende en HTTP POST-forespørsel.
Full kildekoden er tilgjengelig på GitHub.
Demo-appen er et React-program som kommuniserer med tilbudstjenesten, viser alle anførselstegn, og lar deg legge til nye anførselstegn.
Her er et skjermbilde:
App-strukturen er veldig enkel. Jeg startet med et skjelett laget av create-react-app og lagt til to komponenter i src-underkatalogen: QuoteList og AddQuoteForm. Her er katalogstrukturen (unntatt node_modules):
~ / git / reager-data-fetcher> tree -I node_modules -L 2. ├── README.md ├── README2.md ├── package.json ├── offentlig │ ├── favicon.ico │ ├── index.html │ └── manifest.json ├── src │ ├─ ─ AddQuoteForm.css │ ├── AddQuoteForm.js │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── QuoteList.js │ ├── index.css │ ├ ─ - index.js │ └── registerServiceWorker.js └── garn.lock 2 kataloger, 16 filer
Full kildekoden er tilgjengelig på GitLab.
Funksjonell komponent QuoteList viser en liste over anførselstegn som en punktliste. Det forventer en rekke strenger:
Import React fra 'react' const QuoteList = (quotes) => quotes.map (quote =>
Det er en barnekomponent av hovedappkomponenten.
Hent-API er et løftebasert API som returnerer et responsobjekt. For å komme til det faktiske JSON innholdet, må du påkalle json ()
metode for responsobjektet.
fetchQuotes = () => this.setState (... this.state, isFetching: true) hente (QUOTE_SERVICE_URL) .then (response => response.json ()) .then (result => this.setState : resultat, isFetching: false)) .catch (e => console.log (e));
Reaksjonen er selvfølgelig alt om komponenter. Spørsmålet om hvor du skal plassere datainsamlingskoden er viktig. Hvis du faktoriserer koden din, har du mange generiske komponenter og enkelte applikasjonsspesifikke komponenter. Reakt og JavaScript generelt er veldig fleksible, så det er mulig å injisere logikk hvor som helst.
Hente anførselstegn fra en REST API krever noen form for avstemning, siden jeg vil at anførselstegnene alltid skal være oppdaterte. Men den første hentingen er også viktig. Reaktorkomponenter har livssyklusmetoder der du kan implementere logikk som vil utføres på et bestemt tidspunkt. De componentDidMount ()
Metoden branner når komponenten kan nås og tilstanden er endret. Det er det perfekte stedet å starte datainnhenting.
Slik ser det ut:
componentDidMount () this.fetchQuotes ()
Hvis du virkelig ønsker å kutte ned på tiden til første visning, kan du vurdere å bruke componentWillMount ()
å starte din async henting, men du risikerer å ha henting fullført før komponenten er montert. Jeg anbefaler ikke denne tilnærmingen.
Ta en titt på Mastering av metodene for reaktive livscykluser for ytterligere detaljer.
Den første hentes inn componentDidMount ()
er flott, men jeg vil ofte oppdatere sitatene. I en REST-basert API er den eneste løsningen å periodisk avstemme serveren. Sitat tjenesten er veldig grunnleggende og returnerer alltid alle anførselstegn.
Flere skalerbare tjenester vil gi en måte å sjekke om oppdateringer eller til og med bruke HTTP hvis-modifiser-siden eller eTag. Vår demo-applikasjon henter bare alt hvert femte sekund ved å starte en timer i componentDidMount ()
og rydde opp i componentWillUnmount ()
:
componentDidMount () this.fetchQuotes () this.timer = setInterval (() => this.fetchQuotes (), 5000); componentWillUnmount () this.timer = null;
Valgperioden er en appspesifikk avgjørelse. Hvis du trenger oppdateringer i sanntid og / eller polling, stresser du baksiden for mye, bør du vurdere å bruke WebSockets i stedet for REST.
Noen ganger kan datainnhenting ta lang tid. I så fall kan det være en stor del av brukeropplevelsen å vise en fremdriftslinje eller en skinnende animasjon for å la brukeren få vite hva som skjer. Dette er spesielt viktig når brukeren starter datainnhentingen (for eksempel ved å klikke på en søkeknapp).
I demo-appen viser jeg bare en melding som sier "Henter anførselstegn ..." mens en henting pågår. I render ()
metode for hovedapp-komponenten, benytter jeg betinget gjengivelse ved å sjekke state.isFetching
medlem.
render () const title = 'Sitater for deg!' la nå = ny dato () tilbake ();tittel
this.state.isFetching? 'Henter anførselstegn ...': "
De fetchQuotes ()
Metoden tar seg av oppdatering state.isFetching
ved å initialisere den til sant når den starter og sette den tilbake til falsk når du mottar sitatene:
fetchQuotes = () => this.setState (... this.state, isFetching: true) hente (QUOTE_SERVICE_URL) .then (response => response.json ()) .then (result => this.setState : resultat, isFetching: false)) .catch (e => console.log (e));
Jeg gjør det aller minste feilhåndteringen her ved å logge på fangede feil i konsollen. Avhengig av søknaden din, kan du påberope noen retrylogikk, varsle brukeren eller vise noe tilbakebetalingsinnhold.
Fetch API har et par gotchas. Det krever det ekstra trinnet å utvinne JSON fra et svar. Det fanger heller ikke alle feil. For eksempel vil 404 returneres som en vanlig respons. Du må sjekke svarkoden og også håndtere nettverksfeil som blir fanget.
Så du må håndtere feil på to steder. Men du kan bruke axios.js biblioteket til å løse disse problemene og ha litt mer kort kode til prisen for å legge til en ekstern avhengighet. Her ser koden ut med axios:
fetchQuotes = () => this.setState (this.state, isFetching: true) axios.get (QUOTE_SERVICE_URL) .then (response => this.setState (sitater: respons.data, isFetching: false) ) .catch (e => console.log (e);
Dette ser ikke ut som mye, men det hjelper. Koden for å legge til et nytt tilbud er mye mer konsistent med aksjer. Her er hent-versjonen:
handleSubmitWithFetch = event => la data = ny FormData () data.append ('quote', this.state.quote) hente (this.props.quote_service_url, metode: 'POST', kropp: data) .then svar => response.json ()) .catch (e => console.log (e)); event.preventDefault ();
Og her er Axios-versjonen:
handleSubmit = event => axios.post (this.props.quote_service_url, 'quote': this.state.quote) .then (r => console.log (r)) .catch (e => console.log (e)); event.preventDefault ();
I denne opplæringen lærte du hvordan du henter data asynkront i et React-program. Vi diskuterte relevante livssyklusmetoder, avstemning, fremdriftsrapportering og feilhåndtering.
Vi så på to løftebaserte biblioteker: Hent-API og axios.js. Nå går du ut der og bygger fantastiske React-applikasjoner som åpner eksterne APIer.
I løpet av de siste par årene har React vokst i popularitet. Faktisk har vi en rekke elementer på markedet som er tilgjengelige for kjøp, gjennomgang, implementering og så videre. Hvis du leter etter flere ressurser rundt React, ikke nøl med å sjekke dem ut.