Skip to main content

Rendering Lists and Keys

Level: Beginner

ℹ️ What You'll Learn
  • Using .map() to transform arrays into JSX elements
  • The key prop and why it matters for reconciliation
  • Why index as key causes bugs with reordering/deletion
  • Using unique IDs as keys (best practice)
  • Filtering and sorting lists in React
  • Nested lists and complex data structures
  • List performance and optimization
  • Rendering student/teacher/attendance lists in SMS

Why This Matters

Rendering Lists and Keys is part of building maintainable React applications. You will use it when creating student dashboards, forms, tables, API-connected screens, routing flows, and reusable UI components.

Displaying lists of data is one of the most common React tasks. You use map() to transform arrays into components.

The Problem

Beginners often write React code that works for a small demo but becomes difficult when data, forms, API calls, and reusable components grow. This lesson explains Rendering Lists and Keys in a way that helps you build predictable UI for real .NET Web API projects.

Basic List Rendering

function StudentList() {
const students = [
{ id: 1, name: "Ravi Kumar", className: "10" },
{ id: 2, name: "Priya Sharma", className: "10" },
{ id: 3, name: "Arjun Reddy", className: "11" }
];

return (
<ul>
{students.map(student => (
<li>{student.name} - Class {student.className}</li>
))}
</ul>
);
}

map() transforms each student object into a <li> element.

The Key Prop

Always add a key to list items. Keys help React track which items changed.

// ❌ Wrong — no key
<ul>
{students.map(student => (
<li>{student.name}</li>
))}
</ul>

// ✓ Correct — unique key
<ul>
{students.map(student => (
<li key={student.id}>{student.name}</li>
))}
</ul>

Why Keys Matter

Without keys, React doesn't know which item is which:

// Example: User deletes item 2 from list of 3
const [students, setStudents] = useState([
{ id: 1, name: "Ravi" },
{ id: 2, name: "Priya" },
{ id: 3, name: "Arjun" }
]);

// Without key: React thinks "third item just changed to Arjun"
// With key: React knows "item 2 was deleted"

const deleteStudent = (id) => {
setStudents(students.filter(s => s.id !== id));
};

With keys, React re-renders only the changed items. Without keys, it re-renders the entire list.

What Makes a Good Key?

Good keys must be:

  • Unique per item
  • Stable (don't change between renders)
  • Not an array index

Examples of key patterns:

  • Good: key={student.id} — unique database ID
  • Bad: key={index} — breaks if list reorders
  • Bad: key={student.name} — not unique if names repeat
  • Bad: key={Math.random()} — changes every render

Always use IDs from your database. If your data doesn't have IDs, generate them consistently (not with Math.random()).

List with Components

function StudentList() {
const students = [
{ id: 1, name: "Ravi Kumar", marks: 95 },
{ id: 2, name: "Priya Sharma", marks: 88 },
{ id: 3, name: "Arjun Reddy", marks: 92 }
];

return (
<div className="list">
{students.map(student => (
<StudentCard key={student.id} student={student} />
))}
</div>
);
}

function StudentCard({ student }) {
return (
<div className="card">
<h3>{student.name}</h3>
<p>Marks: {student.marks}</p>
</div>
);
}

List with Event Handlers

function StudentList() {
const [students, setStudents] = useState([
{ id: 1, name: "Ravi Kumar" },
{ id: 2, name: "Priya Sharma" },
{ id: 3, name: "Arjun Reddy" }
]);

const deleteStudent = (id) => {
setStudents(students.filter(s => s.id !== id));
};

const editStudent = (id, newName) => {
setStudents(students.map(s =>
s.id === id ? { ...s, name: newName } : s
));
};

return (
<div>
{students.map(student => (
<StudentRow
key={student.id}
student={student}
onDelete={() => deleteStudent(student.id)}
onEdit={() => editStudent(student.id, "New Name")}
/>
))}
</div>
);
}

function StudentRow({ student, onDelete, onEdit }) {
return (
<div className="row">
<span>{student.name}</span>
<button onClick={onEdit}>Edit</button>
<button onClick={onDelete}>Delete</button>
</div>
);
}

Filtering and Sorting Lists

Filter

function ActiveStudentList({ students }) {
const activeStudents = students.filter(s => s.status === 'Active');

return (
<ul>
{activeStudents.map(student => (
<li key={student.id}>{student.name}</li>
))}
</ul>
);
}

Sort

function StudentListByMarks({ students }) {
const sorted = [...students].sort((a, b) => b.marks - a.marks);

return (
<ul>
{sorted.map(student => (
<li key={student.id}>{student.name}: {student.marks}</li>
))}
</ul>
);
}

Note: Use [...students] to avoid modifying original array.

Filter + Sort + Render

function StudentListAdvanced({ students, classFilter, sortBy }) {
const filtered = students.filter(s => s.className === classFilter);

const sorted = [...filtered].sort((a, b) => {
if (sortBy === 'name') {
return a.name.localeCompare(b.name);
}
if (sortBy === 'marks') {
return b.marks - a.marks;
}
return 0;
});

return (
<ul>
{sorted.map(student => (
<li key={student.id}>
{student.name} - {student.marks}
</li>
))}
</ul>
);
}

Nested Lists

function SchoolDashboard() {
const schools = [
{
id: 1,
name: "NexCoding Academy",
students: [
{ id: 101, name: "Ravi" },
{ id: 102, name: "Priya" }
]
},
{
id: 2,
name: "City School",
students: [
{ id: 201, name: "Arjun" },
{ id: 202, name: "Sneha" }
]
}
];

return (
<div>
{schools.map(school => (
<div key={school.id}>
<h2>{school.name}</h2>
<ul>
{school.students.map(student => (
<li key={student.id}>{student.name}</li>
))}
</ul>
</div>
))}
</div>
);
}

Empty States

Always handle empty lists:

function StudentList({ students }) {
if (students.length === 0) {
return <p>No students found.</p>;
}

return (
<ul>
{students.map(student => (
<li key={student.id}>{student.name}</li>
))}
</ul>
);
}

Performance: Memoization (Preview)

For large lists, each render re-creates all student components. React provides optimization:

function StudentList({ students }) {
return (
<ul>
{students.map(student => (
<StudentCard key={student.id} student={student} />
))}
</ul>
);
}

// Memoize to prevent re-renders when props don't change
const StudentCard = React.memo(function StudentCard({ student }) {
return <li>{student.name}</li>;
});

We'll cover this more in Performance article.

Real Example: Teacher Attendance

function TeacherAttendance() {
const [teachers, setTeachers] = useState([
{ id: 1, name: "Dr. Mehta", present: true },
{ id: 2, name: "Mrs. Rao", present: false },
{ id: 3, name: "Mr. Sharma", present: true }
]);

const toggleAttendance = (id) => {
setTeachers(teachers.map(t =>
t.id === id ? { ...t, present: !t.present } : t
));
};

const presentCount = teachers.filter(t => t.present).length;

return (
<div>
<h2>Teacher Attendance</h2>
<p>Present: {presentCount} / {teachers.length}</p>
<table>
<tbody>
{teachers.map(teacher => (
<tr key={teacher.id}>
<td>{teacher.name}</td>
<td>
<input
type="checkbox"
checked={teacher.present}
onChange={() => toggleAttendance(teacher.id)}
/>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}

Key Takeaways

  • Use map() to render lists
  • Always add unique key prop
  • Filter/sort before rendering
  • Handle empty states
  • Keys help React track changes
  • Next: Forms and input
⚠️ Key Mistakes
  1. **No key or key={"{index}"} ** — Causes rendering bugs
  2. Modifying array directly — Use filter/map
  3. Using index as key — Breaks if list reorders
  4. Not handling empty list — Confuses users
💡 Key Selection

If your data doesn't have IDs, generate them consistently (not with Math.random()):

// BAD: random
const key = Math.random();

// GOOD: hash name + timestamp
const key = `${student.name}-${student.enrollDate}`;

// BETTER: Use database IDs
🤖Use AI to Learn Faster

Use ChatGPT, Claude, or Copilot to go deeper on List Rendering. Try these prompts:

  • "Why do you need the key prop?"
  • "What makes a good key vs. bad key?"
  • "How would you filter a list of students by class?"
  • "Quiz me on React list rendering"

💡 Tip: After reading this article, paste your own code into AI and ask "What could go wrong here and why?" — fastest way to find edge cases and deepen understanding.

Quick Definitions

  • Rendering Lists and Keys - The main React concept explained in this lesson.
  • Component - A reusable function that returns UI.
  • Props/state/effects - Core React ideas used to pass data, remember data, and run side effects.
  • Real project usage - How this appears in forms, dashboards, routes, and API-connected pages.

Common Mistakes

  • Copying React code without understanding data flow
  • Mutating arrays or objects directly instead of creating new values
  • Forgetting keys, dependencies, loading states, or error states where needed
  • Putting too much logic in one component
  • Not testing the screen with realistic School Management System data

Practice Task

Create a small React example using Rendering Lists and Keys. Keep it focused on one School Management System screen.

Suggested practice:

  1. Build a small component or page for students, attendance, marks, or fees.
  2. Pass realistic data into the component.
  3. Add one success state and one empty/error state where relevant.
  4. Explain the data flow in your own words.
  5. Rebuild the same example once without looking at the article.

Quick Revision

QuestionAnswer
What is the main idea?Understand and apply Rendering Lists and Keys in React.
Where is it used?Student dashboards, forms, tables, routes, and API-connected screens.
What should beginners focus on?Clear components, predictable data flow, and small examples.
What is the best debugging habit?Check props, state, render output, and browser console step by step.
🎯 How would you explain Rendering Lists and Keys in an interview?

Rendering Lists and Keys is a React concept used to build clear, reusable, and predictable user interfaces. I would explain the problem it solves, show a small component example, and mention a common mistake beginners should avoid.

🎯 Where is this used in a real React project?

It is used in screens like student lists, admission forms, attendance dashboards, marks reports, routing pages, and API-connected admin panels.

Next Article

Forms and Validation ->

nexcoding.in