0Pricing
React Native Academy · Lezione

Composizione di una semplice scheda profilo

Combini View, Text e Image per creare un componente di scheda profilo che mostri avatar, nome e biografia, consolidando le competenze nella composizione dei componenti.

Composizione di una semplice scheda profilo è una lezione React Native Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento React Native Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso React Native Academy include 4 lezioni in totale.

Parti di questa lezione non sono ancora state tradotte e vengono mostrate in inglese.

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.

Domande Frequenti

La lezione «Composizione di una semplice scheda profilo» è gratuita?

Sì — il testo completo di «Composizione di una semplice scheda profilo» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso React Native Academy, passa a CoddyKit PRO. Il corso React Native Academy include 4 lezioni in totale.

Cosa imparerò in «Composizione di una semplice scheda profilo»?

Combini View, Text e Image per creare un componente di scheda profilo che mostri avatar, nome e biografia, consolidando le competenze nella composizione dei componenti. Eserciti React Native Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare React Native Academy?

Non è richiesta alcuna esperienza precedente. React Native Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Composizione di una semplice scheda profilo»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione React Native Academy?

Sì. Ogni lezione React Native Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Il componente View come contenitore
  2. Visualizzazione del testo e stile dei caratteri
  3. Visualizzazione di immagini locali e remote
  4. Composizione di una semplice scheda profilo
← Torna a React Native Academy