Odczytywanie i aktualizowanie stanu magazynu w komponentach
Uzyskuj dostęp do wartości i akcji magazynu w komponencie React Native za pomocą hooka useStore oraz wywołuj aktualizacje po naciśnięciu przycisku lub wysłaniu formularza.
Odczytywanie i aktualizowanie stanu magazynu w komponentach to bezpłatna lekcja React Native Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej React Native Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs React Native Academy zawiera 4 lekcji w sumie.
Części tej lekcji nie zostały jeszcze przetłumaczone i są wyświetlane po angielsku.
Connecting a Component to Zustand
Using a Zustand store in a component is as simple as calling the store hook at the top of the function. The hook is the same object returned by create. You can pass a selector to pick specific values, or read actions directly. No import of useSelector or useDispatch is required — the store hook handles everything.
import { useCounterStore } from '../stores/counterStore';
export default function CounterScreen() {
const count = useCounterStore((state) => state.count);
const increment = useCounterStore((state) => state.increment);
const decrement = useCounterStore((state) => state.decrement);
return (
<View style={styles.container}>
<Text style={styles.count}>{count}</Text>
<Button title='Increment' onPress={increment} />
<Button title='Decrement' onPress={decrement} />
</View>
);
}Selecting Multiple Values Efficiently
To read multiple values from a Zustand store without causing excessive re-renders, you have two options. You can call the store hook multiple times with individual selectors (each subscription is independent), or you can return an object and use the shallow equality helper to compare each property separately.
import { shallow } from 'zustand/shallow';
// Option 1: multiple hooks (preferred for 2-3 values)
const count = useCounterStore((s) => s.count);
const status = useCounterStore((s) => s.status);
// Option 2: shallow equality for multiple values at once
const { count, status } = useCounterStore(
(s) => ({ count: s.count, status: s.status }),
shallow
);Triggering Updates from Button Presses
Zustand actions are plain JavaScript functions, so you pass them directly to React Native event handlers like onPress. You do not need to dispatch an action object or call a helper — just call the function. This makes the component code cleaner and easier to read compared to the Redux dispatch pattern.
export default function TodoInput() {
const [text, setText] = React.useState('');
const addTodo = useTodoStore((state) => state.addTodo);
const handleAdd = () => {
if (text.trim()) {
addTodo(text.trim());
setText('');
}
};
return (
<View>
<TextInput value={text} onChangeText={setText} placeholder='New todo' />
<Button title='Add' onPress={handleAdd} />
</View>
);
}Reading Store State in a FlatList
Zustand stores work naturally with React Native's FlatList. Select the array from the store and pass it to the data prop. Zustand only re-renders this component when the array reference changes, which happens when your store action replaces or mutates the items array and returns a new reference via set.
export default function TodoList() {
const todos = useTodoStore((state) => state.todos);
const removeTodo = useTodoStore((state) => state.removeTodo);
return (
<FlatList
data={todos}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<TouchableOpacity onPress={() => removeTodo(item.id)}>
<Text>{item.text}</Text>
</TouchableOpacity>
)}
/>
);
}Updating Nested State
When your store state has nested objects, pass a function to set and spread the nested level you want to update. Without spreading, set would replace the top-level key entirely, wiping out other nested properties. Alternatively, use the Immer middleware (covered in the previous lesson) to mutate nested values directly.
export const useProfileStore = create<ProfileStore>((set) => ({
profile: {
name: '',
bio: '',
avatar: null,
},
updateName: (name: string) =>
set((state) => ({ profile: { ...state.profile, name } })),
updateBio: (bio: string) =>
set((state) => ({ profile: { ...state.profile, bio } })),
}));Optimistic UI Updates
Optimistic updates improve perceived performance by updating the UI immediately when the user takes an action, before waiting for the server response. In Zustand, call set to update state immediately, then make the API call. If the API fails, call set again to revert the state to its previous value.
toggleLike: async (postId: string) => {
// Update UI immediately
set((state) => ({
posts: state.posts.map((p) =>
p.id === postId ? { ...p, liked: !p.liked } : p
),
}));
try {
await api.toggleLike(postId);
} catch {
// Revert on failure
set((state) => ({
posts: state.posts.map((p) =>
p.id === postId ? { ...p, liked: !p.liked } : p
),
}));
}
}Resetting Store State
A common pattern is to add a reset action that restores the store to its initial state. Store the initial state in a constant outside the create call and reference it in the reset action. This is useful for logout flows where you need to clear all user data from every store at once.
const initialState = { user: null, token: null, isLoggedIn: false };
export const useAuthStore = create<AuthStore>((set) => ({
...initialState,
login: (user, token) => set({ user, token, isLoggedIn: true }),
logout: () => set(initialState), // restore all fields to initial values
}));Watching Store Changes with subscribe
useStore.subscribe lets you react to store changes outside of React components — for example, writing to AsyncStorage whenever settings change, or logging analytics events when specific state transitions occur. Always unsubscribe in the cleanup function to avoid memory leaks.
useEffect(() => {
const unsubscribe = useSettingsStore.subscribe(
(state) => state.theme,
(theme) => {
console.log('Theme changed to:', theme);
AsyncStorage.setItem('theme', theme);
}
);
return unsubscribe; // cleanup on unmount
}, []);Sharing State Between Screens
Because Zustand stores live outside any component tree, they are perfect for sharing state between screens without prop drilling or React Navigation params. Screen A updates the store, Screen B reads from it — both see the same live state immediately. This is much simpler than passing data through route params for deep navigation hierarchies.
// ScreenA.tsx — writes to store
const setSelectedProduct = useProductStore((s) => s.setSelected);
<Button title='View Details' onPress={() => {
setSelectedProduct(product);
navigation.navigate('ProductDetail');
}} />
// ScreenB.tsx — reads from store
const product = useProductStore((s) => s.selected);Testing Zustand Store Actions
Testing a Zustand store is straightforward because it has no dependencies on React. Import the store, call actions directly on getState(), and assert the updated values. You can also reset the store between tests by calling the reset action or overwriting state with setState to ensure test isolation.
import { useCounterStore } from '../counterStore';
before Each(() => {
useCounterStore.getState().reset();
});
test('increment increases count by 1', () => {
useCounterStore.getState().increment();
expect(useCounterStore.getState().count).toBe(1);
});
test('reset brings count back to 0', () => {
useCounterStore.setState({ count: 5 });
useCounterStore.getState().reset();
expect(useCounterStore.getState().count).toBe(0);
});Form State with Zustand
Zustand can manage form state that needs to be shared between multiple screens in a multi-step form flow. Store field values and a current step number in the store, and let each screen read and update only its own fields. On final submission, access the complete form data from getState() in the submit handler.
export const useFormStore = create<FormStore>((set) => ({
step: 1,
name: '',
email: '',
password: '',
setField: (field, value) => set({ [field]: value }),
nextStep: () => set((state) => ({ step: state.step + 1 })),
reset: () => set({ step: 1, name: '', email: '', password: '' }),
}));Quick Check
Test your understanding of React Native Mobile Development concepts from this lesson.
Lesson Recap
In this lesson you learned: calling the store hook with a selector efficiently subscribes a component to only the state it needs, Zustand actions are plain functions that you pass directly to event handlers, and store.subscribe enables side effects like caching or analytics outside the React lifecycle. Next up we explore persisting Zustand state with AsyncStorage.
Często zadawane pytania
Czy lekcja „Odczytywanie i aktualizowanie stanu magazynu w komponentach” jest bezpłatna?
Tak — pełny tekst „Odczytywanie i aktualizowanie stanu magazynu w komponentach” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu React Native Academy, przejdź na CoddyKit PRO. Kurs React Native Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Odczytywanie i aktualizowanie stanu magazynu w komponentach”?
Uzyskuj dostęp do wartości i akcji magazynu w komponencie React Native za pomocą hooka useStore oraz wywołuj aktualizacje po naciśnięciu przycisku lub wysłaniu formularza. Ćwiczysz React Native Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć React Native Academy?
Nie wymagamy żadnego doświadczenia. React Native Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Odczytywanie i aktualizowanie stanu magazynu w komponentach”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji React Native Academy?
Tak. Każda lekcja React Native Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Tworzenie magazynu Zustand
- Odczytywanie i aktualizowanie stanu magazynu w komponentach
- Utrwalanie stanu Zustand za pomocą AsyncStorage
- Wzorzec slice'ów i integracja z DevTools