Worklets og kørsel af kode på UI-tråden
Markér funktioner som worklets med 'worklet'-direktivet, forstå hvorfor det omgår JS-broen, og skriv gesture handlers, der opdaterer shared values direkte.
Worklets og kørsel af kode på UI-tråden er en gratis React Native Academy-lektion på CoddyKit. Dette er lektion 2 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 en worklet?
En worklet er en JavaScript-funktion, som Reanimated kører på brugerfladetråden i stedet for JavaScript-tråden. Reanimateds Babel-plugin registrerer funktioner, der er markeret med direktivstrengen 'worklet' øverst i deres brødtekst, og omdanner dem under bygningen til en form, der kan sendes til og udføres på brugerfladetråden.
Worklets er den centrale mekanisme, der gør det muligt for Reanimated at behandle gestusdata og opdatere animationer billede for billede ved 60 fps uden nogensinde at involvere JavaScript-tråden eller broen. De er den vigtigste arkitektoniske nyskabelse, der adskiller Reanimated fra den klassiske Animated API.
function clamp(value, min, max) {
'worklet'; // directive marks this as a worklet
return Math.min(Math.max(value, min), max);
}
// This function can now be called inside
// useAnimatedStyle, useAnimatedGestureHandler,
// and other Reanimated hooksDirektivet 'worklet'
Strengliteralen 'worklet' øverst i en funktions brødtekst er et særligt direktiv — på samme måde som 'use strict'. Reanimateds Babel-plugin leder efter det og omdanner funktionen, så den kan serialiseres og køres på brugerfladetråden. Uden dette direktiv vil et kald af funktionen fra en worklet-kontekst lydløst blive udført på JS-tråden, hvilket kan medføre nedbrud eller forkert adfærd.
Funktioner, der sendes til Reanimated-hooks som useAnimatedStyle, behandles automatisk som worklets, også uden direktivet. Almindelige hjælpefunktioner, der kaldes FRA disse hooks, skal have direktivet eksplicit.
// Automatically a worklet — Reanimated knows:
const animatedStyle = useAnimatedStyle(() => {
return { opacity: opacity.value };
});
// Utility function needs explicit directive:
function mapRange(value, inMin, inMax, outMin, outMax) {
'worklet';
return ((value - inMin) / (inMax - inMin)) * (outMax - outMin) + outMin;
}Hvorfor brugerfladetråden er vigtig for gestusser
Berøringshændelser på mobilen behandles på brugerfladetråden. Når du trækker en finger, genererer enheden berøringshændelser mange gange i sekundet (op til 120 fps på moderne enheder). Hvis gestushåndtering krævede JavaScript-tråden, skulle hver berøringshændelse krydse broen, hvilket ville introducere forsinkelse og få interaktionerne til at føles langsomme og ufølsomme.
Med worklets kører både gestushåndteringen og animationsreaktionen på brugerfladetråden. Opdateringerne af den animerede værdi sker i samme trådtakt som berøringshændelsen, hvilket giver en ægte gestusrespons uden forsinkelse, der føles som indbyggede iOS-/Android-interaktioner.
Kald af worklets fra animerede handlere
Reanimated tilbyder hooks som useAnimatedScrollHandler og useAnimatedGestureHandler, hvis tilbagekaldsfunktioner kører som worklets på brugerfladetråden. Inde i disse tilbagekald kan du kalde enhver funktion, der er markeret med 'worklet', direkte, og du kan læse og skrive delte værdier ved hjælp af .value.
At skrive til en delt værdi i en gestustilbagekaldsfunktion er den måde, du får en animeret komponent til at følge brugerens finger i realtid — skrivningen sker på brugerfladetråden, og den animerede typografi reagerer med det samme.
import { useAnimatedScrollHandler, useSharedValue } from 'react-native-reanimated';
const scrollY = useSharedValue(0);
const scrollHandler = useAnimatedScrollHandler({
onScroll: (event) => {
'worklet';
scrollY.value = event.contentOffset.y;
},
});runOnJS: Kald af React fra worklets
Worklets kører på brugerfladetråden og kan ikke kalde React-funktioner, setState eller navigationsmetoder direkte. Når du har brug for at udløse kode på JavaScript-tråden fra en worklet (f.eks. opdatere React-state eller navigere, efter en gestus er afsluttet), skal du bruge runOnJS.
runOnJS(fn)(args) planlægger funktionen til at køre på JS-tråden i den næste ledige billedopdatering. På den måde kan gestushandlere opdatere React-state eller kalde navigation efter en interaktion uden at bryde worklettens udførelsesmodel.
import { runOnJS } from 'react-native-reanimated';
const [dismissed, setDismissed] = React.useState(false);
// Inside a gesture handler worklet:
function onSwipeComplete() {
'worklet';
// Cannot call setDismissed directly from UI thread!
runOnJS(setDismissed)(true); // schedules on JS thread
}runOnUI: Kald af worklets fra JS-tråden
Det omvendte af runOnJS er runOnUI. Det giver dig mulighed for at planlægge en worklet-funktion til udførelse på brugerfladetråden fra JavaScript-tråden. Det er nyttigt, når du vil udløse animationer fra hændelseshandlere på JS-tråden (f.eks. knaptryk), samtidig med at selve animationslogikken forbliver i en worklet.
I de fleste tilfælde tildeler du blot en værdi til sharedValue.value (som allerede kører på brugerfladetråden), så runOnUI er mindre ofte nødvendigt. Det bliver nødvendigt, når du skal samle flere handlinger på brugerfladetråden i én atomisk operation.
import { runOnUI } from 'react-native-reanimated';
function triggerComplexAnimation() {
runOnUI(() => {
'worklet';
// These run atomically on the UI thread:
offset.value = withSpring(200);
scale.value = withTiming(0.8, { duration: 300 });
opacity.value = withTiming(0.5, { duration: 300 });
})();
}Begrænsninger ved worklets
Worklets er ikke fuld JavaScript — de kører i et begrænset miljø, der ikke har adgang til Node.js-API'er, React-hooks, komponent-state eller hele JavaScript-kørselsmiljøet. Du kan ikke bruge console.log fra en worklet i produktion (det gør ingenting). Du kan ikke importere tredjepartsmoduler i en worklet, medmindre de udtrykkeligt understøtter Reanimated.
Hold worklets fokuseret på matematik og værdiberegning: begrænsning af værdier, afbildning af intervaller, beregning af fysik og læsning af gestusdata. Flyt alt andet til JS-tråden ved hjælp af runOnJS.
function gestureHandler(event) {
'worklet';
// OK in worklets:
const clamped = Math.max(0, Math.min(event.translationX, 300));
offset.value = clamped;
// NOT OK in worklets:
// console.log('position:', clamped); // no-op in prod
// setReactState(clamped); // crashes - use runOnJS
// navigation.navigate('Screen'); // crashes - use runOnJS
}useAnimatedReaction til overvågning af værdier
useAnimatedReaction lader dig overvåge en delt værdi eller et afledt udtryk og køre en worklet (eller kalde tilbage til JS), når den ændres. Den tager to worklet-funktioner: en prepare-funktion, der læser værdier, og en reaction-funktion, der modtager de aktuelle og tidligere værdier.
Det er nyttigt til at udløse sideeffekter, når en animation når en tærskel — f.eks. at kalde navigation for at lukke en skærm, når en forskydning overstiger 50 % af skærmhøjden.
import { useAnimatedReaction, runOnJS } from 'react-native-reanimated';
useAnimatedReaction(
() => offset.value, // prepare: what to watch
(currentValue, previousValue) => { // reaction: what to do
'worklet';
if (currentValue > 200 && previousValue <= 200) {
runOnJS(onDismiss)(); // notify JS thread
}
}
);useDerivedValue til beregnede delte værdier
useDerivedValue opretter en ny delt værdi, der automatisk beregnes ud fra andre delte værdier. Afledningsfunktionen er en worklet, der kører på brugerfladetråden, hver gang en afhængighed ændres. Det er Reanimateds pendant til useMemo, men for delte værdier.
Brug afledte værdier til at beregne komplekse transformationer én gang (i stedet for at gentage matematikken i hver useAnimatedStyle) eller til at styre flere typografi-hooks fra én fælles sandhedskilde.
import { useDerivedValue } from 'react-native-reanimated';
const progress = useSharedValue(0); // 0 to 1
// Derived: convert progress to translateX
const translateX = useDerivedValue(() => {
'worklet';
return progress.value * 300;
});
// Derived: convert progress to opacity (inverse)
const opacity = useDerivedValue(() => {
'worklet';
return 1 - progress.value;
});Worklets i praksis: parallakse ved rulning
En parallakseoverskrift ved rulning demonstrerer worklets i praksis. Rulleforskydningen styrer flere afledte værdier — et baggrundsbillede bevæger sig med halv hastighed, en titel toner ud, og en fastgjort minioverskrift toner ind. Alle disse afledninger kører som worklets, der udløses af rullesporing med Animated.event.
Hele parallakseeffekten kører ved 60 fps uden involvering af JavaScript-tråden, fordi hvert trin — rullesporing, værdiafledning og typografiberegning — er en worklet på brugerfladetråden.
const scrollY = useSharedValue(0);
const bgTranslateY = useDerivedValue(() => scrollY.value * 0.5);
const titleOpacity = useDerivedValue(() =>
Math.max(0, 1 - scrollY.value / 100)
);
const bgStyle = useAnimatedStyle(() => ({
transform: [{ translateY: bgTranslateY.value }],
}));
const titleStyle = useAnimatedStyle(() => ({
opacity: titleOpacity.value,
}));Fejlfinding af worklets
Det er sværere at fejlfinde worklets end almindelig JavaScript, fordi de kører på en separat tråd. Brug console.log i worklets under udviklingen (det fungerer i fejlsøgningstilstand via Hermes), og brug useAnimatedReaction sammen med runOnJS(console.log) til logning, der er sikker i produktion.
Reanimated integreres også med React DevTools Profiler, så du kan visualisere, hvilke worklets der kører. Hvis animationer opfører sig uventet, kan du tilføje en useDerivedValue for at logge den beregnede værdi ved hver billedopdatering og identificere, hvor beregningen afviger fra forventningerne.
// Development: console.log works in Hermes debug
useAnimatedStyle(() => {
console.log('offset:', offset.value); // OK in dev mode
return { transform: [{ translateX: offset.value }] };
});
// Production-safe logging via runOnJS:
useAnimatedReaction(
() => offset.value,
(val) => runOnJS(console.log)('offset:', val)
);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: worklets er funktioner, der er markeret med direktivet 'worklet' og kører på brugerfladetråden uden om broen, runOnJS planlægger kald på JS-tråden fra worklets til React-state og navigation, og useDerivedValue og useAnimatedReaction lader dig aflede og overvåge delte værdier i en worklet-kontekst. Derefter bygger vi et kort, der kan trækkes, ved hjælp af Pan-gestusser med React Native Gesture Handler.
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 “Worklets og kørsel af kode på UI-tråden” gratis?
Ja — alle 3 lektioner i læringssporet React Native Academy, inklusive “Worklets og kørsel af kode på UI-tråden”, 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 “Worklets og kørsel af kode på UI-tråden”?
Markér funktioner som worklets med 'worklet'-direktivet, forstå hvorfor det omgår JS-broen, og skriv gesture handlers, der opdaterer shared values direkte. 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 2 af 4.
Hvor lang tid tager lektionen “Worklets og kørsel af kode på UI-tråden”?
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
- Installation af Reanimated og shared values
- Worklets og kørsel af kode på UI-tråden
- Pan- og swipe-bevægelser med Gesture Handler
- Pinch-to-zoom og rotation