Pisanie własnych hooków
Wyodrębnij logikę zarządzającą stanem do wielokrotnego użytku własnego hooka, udostępnij go dwóm komponentom i stosuj konwencję nazewnictwa oraz reguły hooków.
Pisanie własnych hooków to bezpłatna lekcja React Native Academy na CoddyKit. To lekcja 4 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.
What Are Custom Hooks?
Custom hooks are JavaScript functions whose names start with use and that may call other React hooks inside them. They let you extract stateful logic from a component into a reusable function. The logic is shared, but each component that calls the custom hook gets its own isolated state — custom hooks are not singletons.
The Rules of Hooks Apply to Custom Hooks
Custom hooks follow the same rules as built-in hooks: only call hooks at the top level (not inside loops or conditions), and only call hooks from React function components or other custom hooks. The use naming prefix is required — it signals to React and linters that the function follows these rules.
// Valid custom hook — starts with 'use'
function useCounter(initialValue) {
const [count, setCount] = useState(initialValue);
const increment = () => setCount(c => c + 1);
const decrement = () => setCount(c => c - 1);
const reset = () => setCount(initialValue);
return { count, increment, decrement, reset };
}A useCounter Custom Hook
The useCounter hook encapsulates a counter's state and its increment, decrement, and reset actions. Any component that needs a counter can call useCounter without repeating the state management logic. Each call to the hook creates an independent counter.
function CounterScreen() {
const { count, increment, decrement, reset } = useCounter(0);
return (
<View>
<Text>Count: {count}</Text>
<Button title='+' onPress={increment} />
<Button title='-' onPress={decrement} />
<Button title='Reset' onPress={reset} />
</View>
);
}A useFetch Custom Hook
A useFetch hook wraps the common pattern of fetching data with useEffect: it manages loading, data, and error states internally, and exposes them to the component. The URL is a dependency — changing it re-triggers the fetch.
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
setLoading(true);
fetch(url)
.then((res) => res.json())
.then((json) => { setData(json); setLoading(false); })
.catch((err) => { setError(err); setLoading(false); });
}, [url]);
return { data, loading, error };
}Using the useFetch Hook
Components using useFetch become dramatically simpler. The component only describes what to render for each state (loading, error, data) without managing any fetch logic itself. If the same endpoint is needed in another screen, just call useFetch again — no code duplication.
function PostsScreen() {
const { data, loading, error } = useFetch('https://jsonplaceholder.typicode.com/posts');
if (loading) return <ActivityIndicator />;
if (error) return <Text>Error: {error.message}</Text>;
return (
<FlatList
data={data}
keyExtractor={(item) => String(item.id)}
renderItem={({ item }) => <Text>{item.title}</Text>}
/>
);
}A useToggle Custom Hook
A useToggle hook simplifies managing boolean state that needs to switch between true and false. It is useful for modals, accordions, dark mode, or any feature that toggles. The hook returns the current value and a stable toggle function.
function useToggle(initialValue = false) {
const [value, setValue] = useState(initialValue);
const toggle = useCallback(() => setValue((v) => !v), []);
return [value, toggle];
}
// Usage
const [isVisible, toggleVisible] = useToggle(false);
<Button title='Show/Hide' onPress={toggleVisible} />
<Modal visible={isVisible} ... />A useForm Custom Hook
A useForm hook manages a form's field values, change handler, and reset action. This pattern eliminates boilerplate in forms across the app. The hook accepts an object of initial field values and returns the current values, a generic field change handler, and a reset function.
function useForm(initialValues) {
const [values, setValues] = useState(initialValues);
const handleChange = useCallback((field, value) => {
setValues((prev) => ({ ...prev, [field]: value }));
}, []);
const reset = useCallback(() => setValues(initialValues), [initialValues]);
return { values, handleChange, reset };
}A useNetworkStatus Custom Hook
A useNetworkStatus hook wraps the NetInfo API to expose the device's online/offline status. Components can simply read the boolean value without knowing about event subscription setup and teardown — the hook handles that internally with a useEffect cleanup function.
import NetInfo from '@react-native-community/netinfo';
function useNetworkStatus() {
const [isOnline, setIsOnline] = useState(true);
useEffect(() => {
const unsubscribe = NetInfo.addEventListener((state) => {
setIsOnline(state.isConnected ?? true);
});
return unsubscribe; // cleanup on unmount
}, []);
return isOnline;
}Sharing Logic Between Components
The real power of custom hooks is sharing logic, not UI. Two screens can both call useNetworkStatus and each gets its own subscription. If the hook has a side effect (like a subscription), it is automatically cleaned up when the component using it unmounts. Each component's hook instance is fully independent.
// Both screens share the same logic, not the same state
function HomeScreen() {
const isOnline = useNetworkStatus();
return <Text>{isOnline ? 'Online' : 'Offline'}</Text>;
}
function ProfileScreen() {
const isOnline = useNetworkStatus(); // independent subscription
return <Banner visible={!isOnline} message='No connection' />;
}Custom Hook Naming and Organization
Name custom hooks descriptively: useAuth, useCart, useDebounce, useWindowDimensions. Store hooks in a dedicated hooks/ directory to keep them organized and findable. Each hook should have a single clear responsibility — avoid creating hooks that do five unrelated things.
// Project structure
src/
hooks/
useAuth.js
useFetch.js
useForm.js
useToggle.js
useNetworkStatus.jsA useDebounce Custom Hook
A useDebounce hook delays propagating a value until a specified time has passed since the last update. This is perfect for search inputs where you want to wait until the user stops typing before firing an API request. The hook uses useEffect and a timer to manage the delay.
function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debouncedValue;
}
// Usage
const debouncedQuery = useDebounce(searchQuery, 400);
useEffect(() => { fetchResults(debouncedQuery); }, [debouncedQuery]);Quick Check
Test your understanding of writing custom hooks from this lesson.
Lesson Recap
In this lesson you learned: custom hooks are functions starting with 'use' that encapsulate stateful logic, each component calling a custom hook gets its own independent state and effects, and organize hooks in a dedicated hooks/ directory for a single responsibility per hook. Next up we explore the Context API for sharing global state without prop drilling.
Często zadawane pytania
Czy lekcja „Pisanie własnych hooków” jest bezpłatna?
Tak — pełny tekst „Pisanie własnych hooków” 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 „Pisanie własnych hooków”?
Wyodrębnij logikę zarządzającą stanem do wielokrotnego użytku własnego hooka, udostępnij go dwóm komponentom i stosuj konwencję nazewnictwa oraz reguły hooków. Ć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 4 z 4.
Ile czasu zajmuje lekcja „Pisanie własnych hooków”?
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
- useRef dla węzłów DOM i wartości zmiennych
- useReducer dla złożonej logiki stanu
- useCallback i useMemo na rzecz wydajności
- Pisanie własnych hooków