React Native Academy · Oppitunti

useRef DOM-solmuille ja muuttuviin arvoihin

Käyttäkää useRefiä TextInput-viittauksen säilyttämiseen ja sen kohdistamiseen ohjelmallisesti sekä sellaisen muuttuvan arvon tallentamiseen, joka säilyy renderöintien välillä käynnistämättä uusia renderöintejä.

Oppitunti 1/413 vaihetta

useRef DOM-solmuille ja muuttuviin arvoihin on ilmainen React Native Academy-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu React Native Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. React Native Academy-kurssilla on yhteensä 4 oppituntia.

Mikä useRef on

useRef on React-hook, joka palauttaa muuttuvan ref-olion. Sen .current-ominaisuus säilyy renderöintien välillä. Toisin kuin tilamuuttujien päivittäminen, ref.current-arvon muuttaminen ei käynnistä uudelleenrenderöintiä. Siksi useRef sopii erinomaisesti usein muuttuvien arvojen tallentamiseen silloin, kun niiden ei pidä aiheuttaa komponentin päivittymistä.

import { useRef } from 'react';

function MyComponent() {
  const myRef = useRef(null);
  // myRef.current starts as null
  // myRef.current persists across re-renders without triggering them
}

Ref-viitteen liittäminen natiivikomponenttiin

Välittäkää ref-viite natiivikomponentille sen ref-propin kautta. React Native täyttää tällöin ref.current-arvon taustalla olevan natiivikomponentin instanssilla. Näin pääsette käyttämään metodeja, kuten focus(), blur() ja measure(), jotka on määritelty natiivikomponentissa.

import { TextInput, Button, View } from 'react-native';
import { useRef } from 'react';

function SearchForm() {
  const inputRef = useRef(null);

  return (
    <View>
      <TextInput ref={inputRef} placeholder='Search...' />
      <Button
        title='Focus Input'
        onPress={() => inputRef.current?.focus()}
      />
    </View>
  );
}

TextInput-komponentin kohdistaminen ohjelmallisesti

Yleinen käyttötapaus on kohdistaa seuraava syöttökenttä automaattisesti, kun käyttäjä painaa näppäimistön Return-näppäintä. Liittäkää ref-viitteet kuhunkin TextInput-komponenttiin ja kutsukaa ensimmäisen kentän onSubmitEditing-käsittelijässä secondInputRef.current.focus()-metodia. Näin mobiililomakkeen näppäimistön käyttö etenee sujuvasti.

function LoginForm() {
  const emailRef = useRef(null);
  const passwordRef = useRef(null);

  return (
    <View>
      <TextInput
        ref={emailRef}
        placeholder='Email'
        returnKeyType='next'
        onSubmitEditing={() => passwordRef.current?.focus()}
      />
      <TextInput
        ref={passwordRef}
        placeholder='Password'
        returnKeyType='done'
        secureTextEntry
      />
    </View>
  );
}

useRef muuttuville arvoille

Toinen tärkeä useRefin käyttötapa on sellaisten muuttuvien arvojen tallentaminen, joiden ei pidä käynnistää uudelleenrenderöintiä. Tallentakaa sinne ajastimen tunniste, animaatiokehyksen käsittelijä, edellinen props-arvo tai mikä tahansa muu usein muuttuva arvo. ref.current-arvon lukeminen tai kirjoittaminen on synkronista eikä aiheuta renderöintikustannusta.

function Timer() {
  const intervalRef = useRef(null);

  const start = () => {
    intervalRef.current = setInterval(() => {
      console.log('tick');
    }, 1000);
  };

  const stop = () => {
    clearInterval(intervalRef.current);
  };

  return <Button title='Start' onPress={start} />;
}

Edellisten tila-arvojen tallentaminen

Hyödyllinen toimintamalli on tallentaa propsin tai tilamuuttujan edellinen arvo ref-viitteen avulla. Kopioikaa nykyinen arvo ref-viitteeseen useEffect-hookissa, joka suoritetaan jokaisen renderöinnin jälkeen. Seuraavan renderöinnin aikana prevRef.current sisältää edellisen renderöintikierroksen arvon, joten voitte verrata vanhaa ja uutta arvoa.

function Counter({ count }) {
  const prevCountRef = useRef(null);

  useEffect(() => {
    prevCountRef.current = count;
  });

  const prevCount = prevCountRef.current;

  return (
    <Text>
      Now: {count} — Before: {prevCount}
    </Text>
  );
}

Vanhentuneiden sulkeumien välttäminen ref-viitteillä

Kerran määritetyt tapahtumankäsittelijät ja callback-funktiot, esimerkiksi ajastimen tai tapahtumakuuntelijan sisällä määritetyt, voivat sisältää tilasta vanhentuneen version. Tallentakaa uusin arvo ref-viitteeseen ja lukekaa arvo ref-viitteestä callback-funktion sisällä, jotta käytössänne on aina viimeisin arvo, vaikka callback olisi luotu useita renderöintejä aiemmin.

function MessageHandler({ onMessage }) {
  const onMessageRef = useRef(onMessage);

  useEffect(() => {
    onMessageRef.current = onMessage; // always up to date
  }, [onMessage]);

  useEffect(() => {
    const subscription = subscribe((msg) => {
      onMessageRef.current(msg); // uses latest callback
    });
    return () => subscription.unsubscribe();
  }, []); // only runs once
}

useRefin ja useState-hookin erot

Keskeinen ero on tämä: useState käynnistää uudelleenrenderöinnin, kun sen arvo päivitetään, mutta useRef ei. Käyttäkää useState-hookia, kun arvon on oltava näkyvissä käyttöliittymässä. Käyttäkää useRef-hookia, kun arvoa käytetään logiikkaan tai sivuvaikutuksiin, mutta sen muuttumisen ei pidä aiheuttaa komponentin uudelleenpiirtoa. Väärän vaihtoehdon valitseminen johtaa joko käyttöliittymän päivitysten jäämiseen väliin tai tarpeettomiin uudelleenrenderöinteihin.

// Triggers re-render — shows updated value on screen
const [count, setCount] = useState(0);

// No re-render — silent counter for internal use only
const renderCount = useRef(0);
renderCount.current += 1;

useRef FlatList-komponentin kanssa

Kun ref liitetään FlatList-komponenttiin, käytettävissänne ovat imperatiiviset metodit, kuten scrollToIndex, scrollToOffset ja scrollToEnd. Tätä voidaan käyttää esimerkiksi takaisin alkuun -painikkeissa, aakkosnavigoinnissa tai automaattiseen vieritykseen juuri lisätyn kohteen kohdalle luettelon loppuun.

function MessageList({ messages }) {
  const listRef = useRef(null);

  useEffect(() => {
    // Scroll to bottom when new message arrives
    listRef.current?.scrollToEnd({ animated: true });
  }, [messages.length]);

  return (
    <FlatList
      ref={listRef}
      data={messages}
      renderItem={({ item }) => <Text>{item.text}</Text>}
      keyExtractor={(item) => item.id}
    />
  );
}

Komponentin asettelun mittaaminen

Kutsukaa ref.current.measure(callback)-metodia lukeaksenne komponentin sijainnin ja koon ikkunaan nähden. Callback saa parametreina arvot x, y, width, height, pageX ja pageY. Tämä on hyödyllistä, kun työkaluvihjeitä, popovereita tai mukautettuja pudotusvalikoita sijoitetaan niiden käynnistäneen komponentin suhteen.

const buttonRef = useRef(null);

const showTooltip = () => {
  buttonRef.current?.measure((x, y, width, height, pageX, pageY) => {
    setTooltipPosition({ top: pageY + height, left: pageX });
    setTooltipVisible(true);
  });
};

<TouchableOpacity ref={buttonRef} onPress={showTooltip}>

Ref-viittausten välittäminen mukautetuille komponenteille

Jos haluatte liittää ref-viittauksen mukautettuun komponenttiin (ettekä sisäänrakennettuun komponenttiin, kuten TextInput), käärikää se React.forwardRef-funktiolla. Kääre välittää ref-viittauksen alla olevalle natiivielementille. Ilman forwardRef-funktiota ref osoittaisi mukautetun komponentin host-objektiin eikä sen sisällä olevaan TextInput-komponenttiin.

const CustomInput = React.forwardRef((props, ref) => (
  <TextInput
    ref={ref}
    style={styles.customInput}
    {...props}
  />
));

// Now you can use the ref on CustomInput
const inputRef = useRef(null);
<CustomInput ref={inputRef} />

useRef:n alustus ja lazy-alustus

Funktiolle useRef(initialValue) annettu argumentti asettaa ref.current-arvon vain ensimmäisen renderöinnin yhteydessä – aivan kuten useState-hookin alkuarvo. Toisin kuin useState-hookissa, käytettävissä ei ole lazy initializer -funktiomuotoa. Jos alkuarvon laskeminen on kallista, laskekaa se ehtolauseessa: if (ref.current === null) ref.current = computeValue().

const cacheRef = useRef(null);

if (cacheRef.current === null) {
  // Expensive computation runs only once
  cacheRef.current = buildLargeDataStructure();
}

// Use cacheRef.current anywhere in the component

Pikatarkistus

Testatkaa, miten hyvin ymmärrätte tämän oppitunnin useRef-hookin.

Oppitunnin kertaus

Tässä oppitunnissa opitte, että useRef tarjoaa muuttuvan .current-ominaisuuden, joka säilyy renderöintien välillä aiheuttamatta uudelleenrenderöintejä, ref-viittauksia liitetään natiivikomponentteihin imperatiivisten metodien, kuten focus(), kutsumiseksi ja ajastinten tunnisteita, aiempia arvoja sekä vakaita callback-funktioita tallennetaan ref-viittauksiin vanhentuneiden sulkeumien välttämiseksi. Seuraavaksi tutustumme useReducer-hookiin monimutkaisen tilalogiikan hallinnassa.

Aloita maksutta

Opi JavaScript tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
30
Oppitunnit
120

Usein kysytyt kysymykset

Onko oppitunti ”useRef DOM-solmuille ja muuttuviin arvoihin” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa React Native Academy-oppimispolun 3 oppituntia, myös oppitunnin “useRef DOM-solmuille ja muuttuviin arvoihin”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. React Native Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”useRef DOM-solmuille ja muuttuviin arvoihin”?

Käyttäkää useRefiä TextInput-viittauksen säilyttämiseen ja sen kohdistamiseen ohjelmallisesti sekä sellaisen muuttuvan arvon tallentamiseen, joka säilyy renderöintien välillä käynnistämättä uusia ren… Harjoittelet React Native Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni React Native Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin React Native Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.

Kuinka kauan ”useRef DOM-solmuille ja muuttuviin arvoihin”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä React Native Academy-oppitunnilla?

Kyllä. Jokainen React Native Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. useRef DOM-solmuille ja muuttuviin arvoihin
  2. useReducer monimutkaiseen tilalogiikkaan
  3. useCallback ja useMemo suorituskyvyn parantamiseen
  4. Mukautettujen hookien kirjoittaminen
← Takaisin: React Native Academy