إنشاء بطاقة ملف شخصي بسيطة
اجمع بين View وText وImage لإنشاء مكوّن بطاقة ملف شخصي يعرض صورة رمزية واسمًا ونبذة، لترسيخ مهارات تركيب المكوّنات.
إنشاء بطاقة ملف شخصي بسيطة درس مجاني في React Native Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في React Native Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة React Native Academy 4 دروس في المجموع.
بعض أجزاء هذا الدرس لم تُترجم بعد وتظهر باللغة الإنجليزية.
Component Composition in React Native
Composition means building big UI from small pieces. A profile card mixes a View, an Image, and Text — and once built, you can reuse it for every user.
// The goal: a reusable ProfileCard component
// that accepts props and renders a complete card UI
// Usage:
<ProfileCard
name='Alice Johnson'
role='Senior Developer'
bio='Building great mobile apps with React Native.'
avatarUri='https://i.pravatar.cc/150?img=1'
followers={1240}
/>Planning the Card Layout
Before coding, plan the card: avatar, name, role, bio, maybe a stats row. A column for the overall layout, a row for side-by-side bits. A quick sketch saves time.
// Conceptual structure (pseudo-code)
<View card>
<Image avatar />
<Text name />
<Text role />
<Text bio />
<View statsRow>
<View stat><Text number/><Text label/></View>
<View stat><Text number/><Text label/></View>
<View stat><Text number/><Text label/></View>
</View>
</View>Building the Card Container
Start with the card container View. Add borderRadius for rounded corners, a shadow for lift, and padding inside. Center the children with alignItems.
import { View, StyleSheet } from 'react-native';
export default function ProfileCard({ children }) {
return (
<View style={styles.card}>
{children}
</View>
);
}
const styles = StyleSheet.create({
card: {
backgroundColor: '#fff',
borderRadius: 20,
padding: 24,
marginHorizontal: 20,
marginVertical: 12,
alignItems: 'center',
shadowColor: '#000',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.1,
shadowRadius: 12,
elevation: 5,
},
});Adding the Avatar Image
Add the avatar at the top: a square View with borderRadius half its size and overflow: hidden makes it a circle. Take the image as a prop to stay reusable.
import { Image, View, StyleSheet } from 'react-native';
function Avatar({ uri, size = 90 }) {
const radius = size / 2;
return (
<View style={[
styles.ring,
{ width: size + 6, height: size + 6, borderRadius: radius + 3 }
]}>
<View style={[
styles.clip,
{ width: size, height: size, borderRadius: radius }
]}>
<Image source={{ uri }} style={{ width: size, height: size }} />
</View>
</View>
);
}
const styles = StyleSheet.create({
ring: { borderWidth: 3, borderColor: '#4f86f7', alignItems: 'center', justifyContent: 'center' },
clip: { overflow: 'hidden', backgroundColor: '#e0e0e0' },
});Name, Role, and Bio Text
Below the avatar, add three Text blocks: a big bold name, a smaller muted role, and a centered bio. A little marginTop between them sets a clean rhythm.
import { Text, StyleSheet } from 'react-native';
function CardInfo({ name, role, bio }) {
return (
<>
<Text style={styles.name}>{name}</Text>
<Text style={styles.role}>{role}</Text>
<Text style={styles.bio} numberOfLines={3}>{bio}</Text>
</>
);
}
const styles = StyleSheet.create({
name: { fontSize: 22, fontWeight: '700', color: '#111', marginTop: 14, textAlign: 'center' },
role: { fontSize: 14, color: '#4f86f7', fontWeight: '500', marginTop: 4, textAlign: 'center' },
bio: { fontSize: 14, color: '#666', lineHeight: 22, marginTop: 10, textAlign: 'center' },
});Stat Counter Row
Many cards end with a stats row: followers and posts side by side. Use flexDirection: row with justifyContent: space-around and a top border to set it off.
import { View, Text, StyleSheet } from 'react-native';
function StatRow({ followers, following, posts }) {
return (
<View style={styles.row}>
<Stat value={posts} label='Posts' />
<Stat value={followers} label='Followers' />
<Stat value={following} label='Following' />
</View>
);
}
function Stat({ value, label }) {
return (
<View style={styles.stat}>
<Text style={styles.value}>{value}</Text>
<Text style={styles.label}>{label}</Text>
</View>
);
}
const styles = StyleSheet.create({
row: { flexDirection: 'row', justifyContent: 'space-around', width: '100%', borderTopWidth: 1, borderTopColor: '#eee', marginTop: 20, paddingTop: 16 },
stat: { alignItems: 'center' },
value: { fontSize: 18, fontWeight: '700', color: '#111' },
label: { fontSize: 12, color: '#999', marginTop: 2 },
});Assembling the Full ProfileCard
Now combine the parts into one ProfileCard that takes props and just renders them. No internal state — pure presentation makes it easy to reuse and test.
import { View, StyleSheet } from 'react-native';
import Avatar from './Avatar';
import CardInfo from './CardInfo';
import StatRow from './StatRow';
export default function ProfileCard({
name, role, bio, avatarUri, followers, following, posts
}) {
return (
<View style={styles.card}>
<Avatar uri={avatarUri} size={90} />
<CardInfo name={name} role={role} bio={bio} />
<StatRow followers={followers} following={following} posts={posts} />
</View>
);
}
const styles = StyleSheet.create({
card: {
backgroundColor: '#fff',
borderRadius: 20,
padding: 24,
marginHorizontal: 20,
alignItems: 'center',
elevation: 5,
shadowColor: '#000',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.1,
shadowRadius: 12,
},
});Rendering Multiple Cards in a List
To show many cards, map over an array of users. For long lists reach for FlatList; for a few, ScrollView is fine. Give each card a unique key.
import { ScrollView } from 'react-native';
import ProfileCard from './ProfileCard';
const users = [
{ id: '1', name: 'Alice', role: 'Designer', bio: 'Crafting beautiful UIs.', avatarUri: 'https://i.pravatar.cc/150?img=1', followers: 980, following: 210, posts: 45 },
{ id: '2', name: 'Bob', role: 'Developer', bio: 'Loves React Native and coffee.', avatarUri: 'https://i.pravatar.cc/150?img=2', followers: 1420, following: 380, posts: 73 },
];
export default function App() {
return (
<ScrollView style={{ backgroundColor: '#f5f5f5' }}>
{users.map(user => (
<ProfileCard key={user.id} {...user} />
))}
</ScrollView>
);
}Adding a Follow Button
Make it interactive with a Follow button using TouchableOpacity. Toggle the label and color, but keep the real API call in the parent via a callback.
import { TouchableOpacity, Text, StyleSheet } from 'react-native';
import { useState } from 'react';
export default function FollowButton({ onPress }) {
const [following, setFollowing] = useState(false);
function handlePress() {
setFollowing(prev => !prev);
onPress && onPress(!following);
}
return (
<TouchableOpacity
style={[styles.btn, following && styles.btnActive]}
onPress={handlePress}
>
<Text style={[styles.label, following && styles.labelActive]}>
{following ? 'Following' : 'Follow'}
</Text>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
btn: { borderWidth: 1.5, borderColor: '#4f86f7', borderRadius: 20, paddingHorizontal: 24, paddingVertical: 8, marginTop: 16 },
btnActive: { backgroundColor: '#4f86f7' },
label: { color: '#4f86f7', fontWeight: '600' },
labelActive: { color: '#fff' },
});Adding Accessibility to the Card
Make the card accessible: set accessible on the outer View with a label that sums it up, so screen readers announce the whole card as one clear unit.
import { View, Text, StyleSheet } from 'react-native';
export default function AccessibleProfileCard({ name, role, followers }) {
const label = `${name}, ${role}, ${followers} followers`;
return (
<View
style={styles.card}
accessible
accessibilityLabel={label}
accessibilityRole='summary'
>
<Text style={styles.name}>{name}</Text>
<Text style={styles.role}>{role}</Text>
<Text style={styles.followers}>{followers} followers</Text>
</View>
);
}
const styles = StyleSheet.create({
card: { padding: 16, borderRadius: 12, backgroundColor: '#fff', elevation: 3 },
name: { fontSize: 20, fontWeight: 'bold' },
role: { color: '#666', marginTop: 4 },
followers: { color: '#4f86f7', marginTop: 8 },
});Skeleton Loading State
While data loads, show a skeleton — grey pulsing boxes shaped like the card. It feels more polished than a spinner and hints at what is coming.
import { View, StyleSheet } from 'react-native';
export default function ProfileCardSkeleton() {
return (
<View style={styles.card}>
{/* Avatar placeholder */}
<View style={styles.avatarSkeleton} />
{/* Name placeholder */}
<View style={styles.nameSkeleton} />
{/* Role placeholder */}
<View style={styles.roleSkeleton} />
{/* Bio placeholder lines */}
<View style={[styles.bioSkeleton, { width: '100%' }]} />
<View style={[styles.bioSkeleton, { width: '80%' }]} />
</View>
);
}
const styles = StyleSheet.create({
card: { padding: 24, borderRadius: 20, backgroundColor: '#fff', alignItems: 'center', margin: 16, elevation: 3 },
avatarSkeleton: { width: 90, height: 90, borderRadius: 45, backgroundColor: '#e0e0e0' },
nameSkeleton: { width: 140, height: 22, borderRadius: 4, backgroundColor: '#e0e0e0', marginTop: 14 },
roleSkeleton: { width: 100, height: 16, borderRadius: 4, backgroundColor: '#e0e0e0', marginTop: 8 },
bioSkeleton: { height: 14, borderRadius: 4, backgroundColor: '#e0e0e0', marginTop: 8 },
});Quick Check
Quick check! See how your ProfileCard skills stack up. 🎉
Lesson Recap
Awesome — you composed a real card! You combined View, Text, and Image, used props to reuse it, and added skeletons for polish. Next up: StyleSheet and Flexbox.
الأسئلة الشائعة
هل درس «إنشاء بطاقة ملف شخصي بسيطة» مجاني؟
نعم — نص درس «إنشاء بطاقة ملف شخصي بسيطة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة React Native Academy، انتقل إلى CoddyKit PRO. تتضمن دورة React Native Academy 4 دروس في المجموع.
ماذا ستتعلم في «إنشاء بطاقة ملف شخصي بسيطة»؟
اجمع بين View وText وImage لإنشاء مكوّن بطاقة ملف شخصي يعرض صورة رمزية واسمًا ونبذة، لترسيخ مهارات تركيب المكوّنات. تتمرن على React Native Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ React Native Academy؟
لا تُشترط خبرة سابقة. React Native Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «إنشاء بطاقة ملف شخصي بسيطة»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس React Native Academy هذا؟
نعم. كل درس في React Native Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- مكوّن View بوصفه حاوية
- عرض النصوص وتنسيق الخطوط
- عرض الصور من مصادر محلية وبعيدة
- إنشاء بطاقة ملف شخصي بسيطة