Hooks المتقدمة — أساسيات React Native
React Hooks المتقدمة
1. useEffect - التأثيرات الجانبية
import { useEffect, useState } from 'react';
function DataFetcher() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
// يعمل عند تحميل المكون
useEffect(() => {
fetchData();
}, []); // المصفوفة الفارغة = مرة واحدة فقط
// يعمل عند تغير قيمة معينة
useEffect(() => {
console.log('Data changed:', data);
}, [data]); // يراقب data
// تنظيف عند إزالة المكون
useEffect(() => {
const timer = setInterval(() => {
console.log('Tick');
}, 1000);
return () => {
clearInterval(timer); // تنظيف
};
}, []);
const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/data');
const json = await response.json();
setData(json);
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
};
if (loading) return <Text>جاري التحميل...</Text>;
return <Text>{JSON.stringify(data)}</Text>;
}
2. useContext - مشاركة البيانات
import { createContext, useContext, useState } from 'react';
// إنشاء Context
const ThemeContext = createContext();
// Provider
function ThemeProvider({ children }) {
const [isDark, setIsDark] = useState(false);
const toggleTheme = () => setIsDark(!isDark);
return (
<ThemeContext.Provider value={{ isDark, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
// استخدام Context
function ThemedButton() {
const { isDark, toggleTheme } = useContext(ThemeContext);
return (
<TouchableOpacity
onPress={toggleTheme}
style={{ backgroundColor: isDark ? '#333' : '#fff' }}
>
<Text style={{ color: isDark ? '#fff' : '#333' }}>
{isDark ? '🌙 داكن' : '☀️ فاتح'}
</Text>
</TouchableOpacity>
);
}
// الاستخدام في App
function App() {
return (
<ThemeProvider>
<ThemedButton />
</ThemeProvider>
);
}
3. useRef - المراجع
import { useRef, useEffect } from 'react';
import { TextInput, TouchableOpacity, Text } from 'react-native';
function FormWithRef() {
const inputRef = useRef(null);
const countRef = useRef(0); // قيمة لا تسبب إعادة رسم
const focusInput = () => {
inputRef.current?.focus();
};
const incrementCount = () => {
countRef.current += 1;
console.log('Count:', countRef.current);
// لا يسبب إعادة رسم!
};
return (
<View>
<TextInput ref={inputRef} placeholder="اكتب هنا" />
<TouchableOpacity onPress={focusInput}>
<Text>Focus</Text>
</TouchableOpacity>
</View>
);
}
4. useMemo - تحسين الأداء
import { useMemo, useState } from 'react';
function ExpensiveList({ items, filter }) {
// يُحسب مرة واحدة فقط عند تغير items أو filter
const filteredItems = useMemo(() => {
console.log('Filtering...');
return items.filter(item =>
item.name.toLowerCase().includes(filter.toLowerCase())
);
}, [items, filter]);
return (
<FlatList
data={filteredItems}
renderItem={({ item }) => <Text>{item.name}</Text>}
/>
);
}
5. useCallback - تذكر الدوال
import { useCallback, useState } from 'react';
function ParentComponent() {
const [count, setCount] = useState(0);
// الدالة تُعاد إنشاؤها فقط عند تغير count
const handlePress = useCallback(() => {
setCount(c => c + 1);
}, []);
return (
<View>
<Text>Count: {count}</Text>
<ChildComponent onPress={handlePress} />
</View>
);
}
// المكون الابن لن يُعاد رسمه بدون سبب
const ChildComponent = React.memo(({ onPress }) => {
console.log('Child rendered');
return (
<TouchableOpacity onPress={onPress}>
<Text>زيادة</Text>
</TouchableOpacity>
);
});
6. Custom Hooks - إنشاء Hooks مخصصة
// useLocalStorage.js
function useAsyncStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(initialValue);
const [loading, setLoading] = useState(true);
useEffect(() => {
loadValue();
}, []);
const loadValue = async () => {
try {
const value = await AsyncStorage.getItem(key);
if (value !== null) {
setStoredValue(JSON.parse(value));
}
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
};
const setValue = async (value) => {
try {
setStoredValue(value);
await AsyncStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error(error);
}
};
return [storedValue, setValue, loading];
}
// الاستخدام
function App() {
const [user, setUser, loading] = useAsyncStorage('user', null);
if (loading) return <Text>Loading...</Text>;
return <Text>مرحباً {user?.name}</Text>;
}
اختبر فهمك