قراءة الحالة باستخدام useSelector
استخدم hook useSelector لقراءة القيم من المتجر داخل مكوّن، واكتب دوال selector لاشتقاق بيانات محسوبة من الحالة الخام.
قراءة الحالة باستخدام useSelector درس مجاني في React Native Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في React Native Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة React Native Academy 4 دروس في المجموع.
بعض أجزاء هذا الدرس لم تُترجم بعد وتظهر باللغة الإنجليزية.
What Is useSelector?
useSelector is a hook from react-redux that lets a component read data from the Redux store. It accepts a selector function as its argument. The selector receives the entire root state and returns only the piece of data that component needs. When that piece of data changes, React re-renders the component automatically.
Basic useSelector Usage
Call useSelector inside a functional component, passing an arrow function that extracts the value you need from the global state. The hook subscribes to the store and triggers a re-render only when the selected value changes, avoiding unnecessary re-renders if unrelated parts of the state update.
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>
);
}Using Typed useAppSelector
In TypeScript projects, use the pre-typed useAppSelector hook you created in the hooks file. This eliminates the need to annotate the state parameter every time you call the hook. Your editor will also autocomplete state property names, making it faster to write selectors correctly.
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>;
}What Is a Selector Function?
A selector is simply a function that takes the Redux state as an argument and returns a derived value. Keeping selectors separate from components promotes reuse — many components can use the same selector. You can also compose selectors to derive more complex computed values from raw state data.
// 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);Re-render Behavior of useSelector
useSelector uses strict equality (===) to compare the previous and next selected values. The component re-renders only when the returned value changes. If your selector returns an object or array literal (like state.items.filter(...)), it will return a new reference on every call, causing unnecessary re-renders. Keep selectors returning primitives or memoize them.
// 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 reselectMemoized Selectors with reselect
The reselect library (included in RTK) provides createSelector for building memoized selectors. A memoized selector caches its last result and only recomputes when its input selectors return different values. This prevents expensive derivations from running on every state update when only unrelated parts of state changed.
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)
);Selecting Nested State
You can drill as deep as needed into the state tree inside a selector. For complex state shapes, chain property accesses carefully and handle optional chaining (?.) to avoid runtime errors if a slice has not yet loaded data. Keep selectors readable by giving them meaningful names that describe what data they return.
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)
);Combining Multiple Selectors
A single component can call useSelector multiple times to read different pieces of state, or you can call it once and destructure from a selector that returns an object. Calling it multiple times is preferred because each subscription is independent — the component only re-renders when one of the selected values actually changes.
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>
);
}Selector Co-location Pattern
A popular pattern is to define selectors inside the slice file alongside the reducers. Prefix them with select and export them named. This co-location makes it easy to find and update a selector if the state shape changes, since both the reducer and the selector live in the same file.
// 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);Avoiding Object Returns in useSelector
If you must return an object from useSelector, use the shallowEqual comparator as the second argument. This compares each property of the returned object separately, preventing re-renders when the object's contents have not changed but the reference is new. Import shallowEqual from react-redux.
import { useSelector, shallowEqual } from 'react-redux';
const { name, email } = useAppSelector(
(state) => ({ name: state.user.name, email: state.user.email }),
shallowEqual
);useSelector vs mapStateToProps
The older connect(mapStateToProps) higher-order component pattern achieves the same goal as useSelector but with more boilerplate. Hooks are the modern, preferred approach because they require less code, work inside any functional component, and compose naturally with other hooks. The connect API is still supported but not recommended for new code.
Quick Check
Test your understanding of React Native Mobile Development concepts from this lesson.
Lesson Recap
In this lesson you learned: useSelector subscribes a component to a slice of Redux state and re-renders when that value changes, selector functions keep data derivation logic reusable and testable, and createSelector memoizes expensive computations to prevent unnecessary re-renders. Next up we explore async thunks with createAsyncThunk.
الأسئلة الشائعة
هل درس «قراءة الحالة باستخدام useSelector» مجاني؟
نعم — نص درس «قراءة الحالة باستخدام useSelector» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة React Native Academy، انتقل إلى CoddyKit PRO. تتضمن دورة React Native Academy 4 دروس في المجموع.
ماذا ستتعلم في «قراءة الحالة باستخدام useSelector»؟
استخدم hook useSelector لقراءة القيم من المتجر داخل مكوّن، واكتب دوال selector لاشتقاق بيانات محسوبة من الحالة الخام. تتمرن على React Native Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ React Native Academy؟
لا تُشترط خبرة سابقة. React Native Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «قراءة الحالة باستخدام useSelector»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس React Native Academy هذا؟
نعم. كل درس في React Native Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- إعداد Redux Store وProvider
- إنشاء Slices باستخدام createSlice
- قراءة الحالة باستخدام useSelector
- Async Thunks باستخدام createAsyncThunk