Listojen renderöinti
Saatat usein haluta näyttää useita samanlaisia komponentteja datakokoelmasta. Voit käyttää JavaScriptin listametodeja manipuloidaksesi tietojoukkoja. Tällä sivulla tulet käyttämään filter()
ja map()
metodeita Reactissa suodattaaksesi ja muuttaaksesi tietojoukon komponenttitaulukoksi.
Tulet oppimaan
- Miten komponentteja renderöidään listasta käyttäen JavaScriptin
map()
metodia - Miten renderöidään tiettyjä komponentteja käyttäen JavaScriptin
filter()
metodia - Miksi ja milloin käyttää React key:ta
Tietojen renderöinti taulukosta
Sanotaan, että sinulla on taulukko sisältöä.
<ul>
<li>Creola Katherine Johnson: mathematician</li>
<li>Mario José Molina-Pasquel Henríquez: chemist</li>
<li>Mohammad Abdus Salam: physicist</li>
<li>Percy Lavon Julian: chemist</li>
<li>Subrahmanyan Chandrasekhar: astrophysicist</li>
</ul>
Ainoa ero taulukon alkioiden välillä on niiden sisältö eli data. Usein täytyy näyttää useita ilmentymiä samasta komponentista eri datalla käyttöliittymiä rakentaesa: kommenttilistoista profiilikuvien gallerioihin. Näissä tilanteissa voit tallentaa datan JavaScriptin olioihin ja taulukoihin käyttämällä metodeja kuten map()
](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) ja filter()
renderöidäksesi niistä komponenttilistan.
Tässä lyhyt esimerkki miten luoda kohdelistaus tietojoukosta:
- Siirrä datat taulukkoon:
const people = [
'Creola Katherine Johnson: mathematician',
'Mario José Molina-Pasquel Henríquez: chemist',
'Mohammad Abdus Salam: physicist',
'Percy Lavon Julian: chemist',
'Subrahmanyan Chandrasekhar: astrophysicist'
];
- Mäppää
people
kohteet uuteen taulukkoonlistItems
koostuen JSX:sta:
const listItems = people.map(person => <li>{person}</li>);
- Palauta
listItems
komponentistasi käärittynä<ul>
sisään:
return <ul>{listItems}</ul>;
Tässä lopputulos:
const people = [ 'Creola Katherine Johnson: mathematician', 'Mario José Molina-Pasquel Henríquez: chemist', 'Mohammad Abdus Salam: physicist', 'Percy Lavon Julian: chemist', 'Subrahmanyan Chandrasekhar: astrophysicist' ]; export default function List() { const listItems = people.map(person => <li>{person}</li> ); return <ul>{listItems}</ul>; }
Huomaa hiekkalaatikko yllä, joka näyttää konsolivirheen:
Opit miten tämä virhe korjataan myöhemmin tällä sivulla. Ennen kuin menemme siihen, jäsennetään dataasi hieman.
Taulukon tietojen suodattaminen
Tätä dataa voidaan jäsentää vielä enemmän.
const people = [{
id: 0,
name: 'Creola Katherine Johnson',
profession: 'mathematician',
}, {
id: 1,
name: 'Mario José Molina-Pasquel Henríquez',
profession: 'chemist',
}, {
id: 2,
name: 'Mohammad Abdus Salam',
profession: 'physicist',
}, {
name: 'Percy Lavon Julian',
profession: 'chemist',
}, {
name: 'Subrahmanyan Chandrasekhar',
profession: 'astrophysicist',
}];
Sanotaan, että haluat näyttää vain henkilöt joiden ammatti on 'chemist'
. Voit käyttää JavaScriptin filter()
metodia palauttaaksesi vain ne henkilöt. Tämä metodi ottaa talukon kohteista ja välittää ne “testin” läpi (funktion, joka palauttaa true
tai false
) ja palauttaa uuden taulukon sisältäen vain ne kohteet jotka läpäisiviät testin (palautti true
).
Haluat vain kohteet joissa profession
on 'chemist'
. Tämä “testaus” funktio tälle näyttäisi seuraavalta (person) => person.profession === 'chemist'
. Tässä kuinka se vielä kootaan:
- Luo uusi taulukko
chemists
sisältäen vain “chemist” henkilöt kutsumallafilter()
metodiapeople
taulukossa suodattaenperson.profession === 'chemist'
:
const chemists = people.filter(person =>
person.profession === 'chemist'
);
- Nyt mäppää
chemists
:
const listItems = chemists.map(person =>
<li>
<img
src={getImageUrl(person)}
alt={person.name}
/>
<p>
<b>{person.name}:</b>
{' ' + person.profession + ' '}
known for {person.accomplishment}
</p>
</li>
);
- Lopuksi, palauta
listItems
komponentistasi:
return <ul>{listItems}</ul>;
import { people } from './data.js'; import { getImageUrl } from './utils.js'; export default function List() { const chemists = people.filter(person => person.profession === 'chemist' ); const listItems = chemists.map(person => <li> <img src={getImageUrl(person)} alt={person.name} /> <p> <b>{person.name}:</b> {' ' + person.profession + ' '} known for {person.accomplishment} </p> </li> ); return <ul>{listItems}</ul>; }
Listojen pitäminen järjestyksessä käyttämällä key
:ta
Huomaa, että kaikki alla yllä olevat hiekkalaatikot näyttävät virheen konsolissa:
Joudut antamaan jokaiselle taulukon kohteelle key
:n — merkkijonon tai numeron joka tunnistaa yksilöllisesti sen muista taulukon kohteista:
<li key={person.id}>...</li>
Avaimet kertovat Reactille mitkä taulukon kohteet vastaavat mitäkin komponenttia, jotta se voi yhdistää ne myöhemmin. Tästä tulee tärkeää jos taulukon kohteet voivat liikkua (esim. suodatuksen seurauksena), kohteita lisätään tai poistetaan. Hyvin valittu key
auttaa Reactia päättämään mitä oikeastaan on tapahtunut tehdäkseen oikeat päivitykset DOM-puuhun.
Sen sijaan, että avaimet luotaisiin lennosta, kannattaa sisällyttää ne datassasi:
export const people = [{ id: 0, // Used in JSX as a key name: 'Creola Katherine Johnson', profession: 'mathematician', accomplishment: 'spaceflight calculations', imageId: 'MK3eW3A' }, { id: 1, // Used in JSX as a key name: 'Mario José Molina-Pasquel Henríquez', profession: 'chemist', accomplishment: 'discovery of Arctic ozone hole', imageId: 'mynHUSa' }, { id: 2, // Used in JSX as a key name: 'Mohammad Abdus Salam', profession: 'physicist', accomplishment: 'electromagnetism theory', imageId: 'bE7W1ji' }, { id: 3, // Used in JSX as a key name: 'Percy Lavon Julian', profession: 'chemist', accomplishment: 'pioneering cortisone drugs, steroids and birth control pills', imageId: 'IOjWm71' }, { id: 4, // Used in JSX as a key name: 'Subrahmanyan Chandrasekhar', profession: 'astrophysicist', accomplishment: 'white dwarf star mass calculations', imageId: 'lrWQx8l' }];
Syväsukellus
Mitä teet kun yhden kohteen täytyy renderlidä useampi DOM-kohde?
Lyhyt <>...</>
Fragment-syntaksi ei anna sinun välittää avainta, joten joudut joko sisällyttämään ne <div>
:n sisälle, tai voit käyttää hieman pitempää ja eksplisiittisempää <Fragment>
syntaksia:
import { Fragment } from 'react';
// ...
const listItems = people.map(person =>
<Fragment key={person.id}>
<h1>{person.name}</h1>
<p>{person.bio}</p>
</Fragment>
);
Fragmentit häviävät DOM:sta, joten tämä tuottaa tasaisen listauksen elementeistä <h1>
, <p>
, <h1>
, <p>
, ja niin edelleen.
Mistä saat key
:n
Eri tietolähteet tarjoavat eri lähteet avaimille:
- Data tietokannasta: Jos datasi tulee tietokannasta, voit käyttää tietokannan avaimia/ID:tä, jotka ovat luonnostaan uniikkeja.
- Paikallisesti luotu data: Jos datasi on luotu ja tallennettu paikallisesti (esim. muistiinpanot muistiinpanosovelluksessa), käytä kasvavaa laskuria,
crypto.randomUUID()
:ta, tai a pakettia kutenuuid
kohteita luodessa.
Avainten säännöt
- Avainten on oltava uniikkeja sen sisaruksiin nähden. Kuitenkin, on sallittau käyttää samoja avaimia JSX kohteissa eri taulukoissa.
- Avaimet eivät saa muuttua tai se tuhoaa niiden koko tarkoituksen! Älä luo niitä kun renderöidään.
Miksi React tarvitsee avaimia?
Kuvittele, että tiedostoilla työpöydälläsi ei olisi nimiä. Sen sijaan viittaisit niihin niiden järjestyksen perusteella — ensimmäinen tiedosto, toinen tiedosto, ja niin edelleen. Voisit tottua siihen, mutta kun poistat tiedoston niin siitä tulisi sekavaa. Toisesta tiedostosta tulisi ensimmäinen, kolmannesta toinen, ja niin edelleen.
Tiedostonimet kansioissa ja JSX avaimet taulukossa palvelevat samantapaiseen tarkoitukseen. Sen avulla voidaan yksilöidä kohteet sen sisaruksista. Hyvin valittu avain tarjoaa enemmän tietoa kuin pelkän sijainnin taulukossa. Vaikka sijainti muuttuisi uudelleenjärjestyksen seurauksena, key
:n avulla React tunnistaa kohteet sen elinkaaren aikana.
Kertaus
Tällä sivulla olet oppinut:
- Miten siirtää dataa komponenteista ulos tietorakenteisiin kuten taulukoihin ja olioihin.
- Miten luodaan joukkoja samanlaisia komponentteja käyttämällä JavaScript:n
map()
metodia. - Miten luodaan taulukkoja suodatetuista kohteista käyttämällä JavaScript:n
filter()
metodia. - Miksi ja miten asetetaan
key
jokaisen kokoelman komponentille, jotta React voi pitää kohteita yllä vaikka niiden sijainti tai data muuttuisi.
Haaste 1 / 4: Listan jakaminen kahteen
Tämä esimerkki näyttää listan kaikista henkilöistä.
Muuta se näyttämään kaksi erillistä listaa toinen toisensa jälkeen: Chemists ja Everyone Else. Kuten aiemmin, voit määritellä mikäli henkilö on kemisti tarkistamalla jos person.profession === 'chemist'
.
import { people } from './data.js'; import { getImageUrl } from './utils.js'; export default function List() { const listItems = people.map(person => <li key={person.id}> <img src={getImageUrl(person)} alt={person.name} /> <p> <b>{person.name}:</b> {' ' + person.profession + ' '} known for {person.accomplishment} </p> </li> ); return ( <article> <h1>Scientists</h1> <ul>{listItems}</ul> </article> ); }