React Native Academy · Lektion

Læsning af state med useSelector

Brug useSelector-hooket til at læse værdier fra store i en komponent, og skriv selector-funktioner, der udleder beregnede data fra rå state.

Lektion 3 af 413 trin

Læsning af state med useSelector er en gratis React Native Academy-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i React Native Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. React Native Academy-kurset indeholder 4 lektioner i alt.

Hvad er useSelector?

useSelector er en hook fra react-redux, der lader en komponent læse data fra Redux-storet. Den accepterer en selectorfunktion som argument. Selectoren modtager hele rodtilstanden og returnerer kun det stykke data, som komponenten har brug for. Når dette stykke data ændres, gengiver React automatisk komponenten igen.

Grundlæggende brug af useSelector

Kald useSelector inde i en funktionel komponent, og giv den en arrow-funktion, der udtrækker den værdi, du har brug for, fra den globale tilstand. Hooket abonnerer på storet og udløser kun en ny rendering, når den valgte værdi ændres. Dermed undgår du unødvendige nye renderinger, hvis irrelevante dele af tilstanden opdateres.

import React from 'react';
import { View, Text } from 'react-native';
import { useSelector } from 'react-redux';
import type { RootState } from '../../store';

export default function CounterDisplay() {
  const count = useSelector((state: RootState) => state.counter.value);

  return (
    <View>
      <Text>Count: {count}</Text>
    </View>
  );
}

Brug af den typede useAppSelector

I TypeScript-projekter skal du bruge det forudtypede useAppSelector-hook, du oprettede i hooks-filen. Så behøver du ikke annotere state-parameteren, hver gang du kalder hooket. Din editor fuldfører også navne på tilstandsegenskaber automatisk, så du hurtigere kan skrive korrekte selektorer.

import { useAppSelector } from '../../store/hooks';

export default function CounterDisplay() {
  // No need to annotate RootState — it is inferred automatically
  const count = useAppSelector((state) => state.counter.value);
  const status = useAppSelector((state) => state.counter.status);

  return <Text>{status === 'loading' ? 'Loading...' : count}</Text>;
}

Hvad er en selektorfunktion?

En selektor er ganske enkelt en funktion, der tager Redux-tilstanden som argument og returnerer en afledt værdi. Når selektorer holdes adskilt fra komponenterne, bliver de genanvendelige — mange komponenter kan bruge den samme selektor. Du kan også kombinere selektorer for at udlede mere komplekse beregnede værdier fra rå tilstandsdata.

// selectors.ts
import type { RootState } from './store';

export const selectCount = (state: RootState) => state.counter.value;
export const selectDoubledCount = (state: RootState) => state.counter.value * 2;

// In component:
const count = useAppSelector(selectCount);
const doubled = useAppSelector(selectDoubledCount);

Hvordan useSelector renderer komponenter igen

useSelector bruger streng lighed (===) til at sammenligne de tidligere og de nye valgte værdier. Komponenten renderer kun igen, når den returnerede værdi ændres. Hvis din selektor returnerer et objekt eller en array-literal (som state.items.filter(...)), returnerer den en ny reference ved hvert kald, hvilket medfører unødvendige nye renderinger. Sørg for, at selektorer returnerer primitive værdier, eller memoiser dem.

// This runs a filter on every store update — returns new array each time!
const activeItems = useAppSelector(
  (state) => state.todos.filter((t) => t.active) // Bad for performance
);

// Better: use a stable reference or memoize with reselect

Memoiserede selektorer med reselect

Biblioteket reselect (som er inkluderet i RTK) indeholder createSelector til opbygning af memoiserede selektorer. En memoiseret selektor gemmer sit seneste resultat i en cache og genberegner det kun, når dens inputselektorer returnerer andre værdier. Det forhindrer dyre beregninger i at køre ved hver tilstandsopdatering, når kun irrelevante dele af tilstanden er ændret.

import { createSelector } from '@reduxjs/toolkit';
import type { RootState } from './store';

const selectTodos = (state: RootState) => state.todos.items;
const selectFilter = (state: RootState) => state.todos.filter;

export const selectFilteredTodos = createSelector(
  [selectTodos, selectFilter],
  (todos, filter) => todos.filter((t) => t.status === filter)
);

Valg af indlejret tilstand

Du kan gå så dybt ned i tilstandstræet, som du har brug for, inde i en selektor. Ved komplekse tilstandsstrukturer skal du kæde egenskabsopslag omhyggeligt sammen og håndtere valgfri chaining (?.) for at undgå runtime-fejl, hvis en slice endnu ikke har indlæst data. Gør selektorer lette at læse ved at give dem sigende navne, der beskriver, hvilke data de returnerer.

const userName = useAppSelector((state) => state.user.profile?.name ?? 'Guest');
const cartTotal = useAppSelector((state) =>
  state.cart.items.reduce((sum, item) => sum + item.price * item.qty, 0)
);

Kombination af flere selektorer

En enkelt komponent kan kalde useSelector flere gange for at læse forskellige dele af tilstanden, eller du kan kalde det én gang og destructure resultatet fra en selektor, der returnerer et objekt. Det foretrækkes at kalde det flere gange, fordi hvert abonnement er uafhængigt — komponenten renderer kun igen, når en af de valgte værdier faktisk ændres.

export default function ProfileScreen() {
  const name = useAppSelector((state) => state.user.name);
  const email = useAppSelector((state) => state.user.email);
  const isPremium = useAppSelector((state) => state.subscription.tier === 'premium');

  return (
    <View>
      <Text>{name}</Text>
      <Text>{email}</Text>
      {isPremium && <Text>Premium Member</Text>}
    </View>
  );
}

Mønsteret med samplacering af selektorer

Et populært mønster er at definere selektorer inde i slice-filen ved siden af reducerne. Sæt præfikset select foran dem, og eksportér dem med navne. Samplaceringen gør det nemt at finde og opdatere en selektor, hvis tilstandsstrukturen ændres, fordi både reduceren og selektoren ligger i den samme fil.

// counterSlice.ts
export const selectCount = (state: RootState) => state.counter.value;
export const selectStatus = (state: RootState) => state.counter.status;

// In component:
import { selectCount, selectStatus } from './counterSlice';
const count = useAppSelector(selectCount);

Undgå objekter som returværdi fra useSelector

Hvis du er nødt til at returnere et objekt fra useSelector, skal du bruge sammenligningsfunktionen shallowEqual som det andet argument. Den sammenligner hver egenskab i det returnerede objekt separat og forhindrer nye renderinger, når objektets indhold ikke er ændret, men referencen er ny. Importér shallowEqual fra react-redux.

import { useSelector, shallowEqual } from 'react-redux';

const { name, email } = useAppSelector(
  (state) => ({ name: state.user.name, email: state.user.email }),
  shallowEqual
);

useSelector sammenlignet med mapStateToProps

Det ældre mønster med higher-order-komponenten connect(mapStateToProps) opnår det samme som useSelector, men kræver mere standardkode. Hooks er den moderne og foretrukne tilgang, fordi de kræver mindre kode, fungerer i alle funktionelle komponenter og naturligt kan kombineres med andre hooks. connect-API'et understøttes stadig, men anbefales ikke til ny kode.

Hurtigt tjek

Test din forståelse af begreberne inden for React Native Mobile Development fra denne lektion.

Opsummering af lektionen

I denne lektion har du lært, at useSelector abonnerer på en komponent til en del af Redux-tilstanden og renderer den igen, når værdien ændres, at selektorfunktioner holder logikken til afledning af data genanvendelig og testbar, og at createSelector memoiserer dyre beregninger for at forhindre unødvendige nye renderinger. Næste gang ser vi på asynkrone thunks med createAsyncThunk.

Gratis at komme i gang

Lær JavaScript med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
30
Lektioner
120

Ofte stillede spørgsmål

Er lektionen “Læsning af state med useSelector” gratis?

Ja — alle 3 lektioner i læringssporet React Native Academy, inklusive “Læsning af state med useSelector”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. React Native Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Læsning af state med useSelector”?

Brug useSelector-hooket til at læse værdier fra store i en komponent, og skriv selector-funktioner, der udleder beregnede data fra rå state. Du øver dig i React Native Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på React Native Academy?

Der kræves ingen tidligere erfaring. React Native Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.

Hvor lang tid tager lektionen “Læsning af state med useSelector”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne React Native Academy-lektion?

Ja. Alle React Native Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Opsætning af Redux-store og Provider
  2. Oprettelse af slices med createSlice
  3. Læsning af state med useSelector
  4. Asynkrone thunks med createAsyncThunk
← Tilbage til React Native Academy