Skip to content

Conversation

@nishi240931
Copy link

@nishi240931 nishi240931 commented Jan 3, 2026

This PR fixes unstable React key usage in the protocol card list.

Summary by CodeRabbit

  • New Features

    • CTA now supports custom link destinations and button text for richer call-to-action behavior.
  • Bug Fixes

    • Improved list rendering stability to reduce UI inconsistencies during page updates.
  • Style

    • Removed large header/intro blocks for a cleaner Protocols page and applied minor container spacing tweaks.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 3, 2026

📝 Walkthrough

Walkthrough

Removed commented header blocks on the Protocols page, replaced index-based Card keys with protocol.title, updated CTA invocation to include link and linkText, and removed the index prop from the Card component's Props/signature.

Changes

Cohort / File(s) Summary
Protocols page
app/protocols/page.tsx
Removed large commented header/intro blocks; changed Card key from index to protocol.title; passed new props link and linkText to CTA; minor whitespace/layout tweaks.
Card component API
components/card.tsx
Removed index: number from Props and updated Card signature to no longer accept index; renamed map callback param and switched generated span keys to ${item}-${index}.

Sequence Diagram(s)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • Zahnentferner

Poem

🐰 I nibble through code in the glade,

Keys aligned, old crumbs all laid.
Props rearranged, a tidy hop,
Cards now steady — no more drop.
Hooray! A rabbit's tiny hop. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The linked issue #28 requires creating a footer component, but the PR changes only fix key usage in protocol cards with no footer implementation. The PR addresses a different concern (key stability) than the linked issue (footer creation). Clarify whether this PR should be linked to #28 or if a separate issue for key stability should be created.
Out of Scope Changes check ⚠️ Warning The PR includes out-of-scope changes: it fixes key usage and removes the index prop from Card, but the linked issue #28 is about creating a footer component. The changes are unrelated to the footer objective in issue #28. Either link to a different issue about key stability or update the PR description to clarify the actual scope.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix unstable key usage in protocol card list' directly aligns with the main change: replacing array index keys with stable keys in the Card component.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
app/protocols/page.tsx (1)

102-102: Remove the unused index prop from the Card component.

The index prop is declared in the Card interface and destructured but never used in the component. Now that the key is based on protocol.title, the index prop can be safely removed from both the Card component definition (components/card.tsx) and the prop passed in app/protocols/page.tsx.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 789c5f3 and ccf21f9.

📒 Files selected for processing (1)
  • app/protocols/page.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
app/protocols/page.tsx (1)
components/container.tsx (1)
  • Container (1-15)
🔇 Additional comments (3)
app/protocols/page.tsx (3)

101-101: Excellent fix for React key stability!

Using protocol.title as the key instead of the array index ensures stable component identity across re-renders. All protocol titles in the protocols1 array are unique, making this a reliable and stable key.


86-120: Note: Mismatch between PR description and linked issue.

The PR description references issue #28 ("Add footer"), but the actual changes in this PR are focused on fixing unstable key usage in the protocol card list. The linked issue objectives don't appear to relate to the key stability fix implemented here.

Consider verifying that the correct issue is linked or updating the PR description to accurately reflect the changes.


112-117: No action required. The CTA component properly accepts and implements the link and linkText props as shown in its definition (components/cta.tsx lines 3-27). The component signature includes both props in the Props interface, and they are correctly used in the Link component and span rendering.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
components/card.tsx (1)

33-40: Fix: Same unstable key pattern found inside Card component.

While this PR fixes unstable keys at the page level, the same anti-pattern remains here. The map function uses array index (key) as the React key for description line items. If description lines are reordered or modified, React reconciliation will be unstable.

🔎 Proposed fix using content-based key
-            {description.split("\n").map((item, key) => {
+            {description.split("\n").map((item, index) => {
               return (
-                <span key={key}>
+                <span key={`${item}-${index}`}>
                   {item}
                   <br />
                 </span>
               )
             })}

Note: Using a composite key ${item}-${index} provides better stability when content changes, though if line content is unique, key={item} alone would suffice.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ccf21f9 and e483319.

📒 Files selected for processing (2)
  • app/protocols/page.tsx
  • components/card.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
app/protocols/page.tsx (1)
components/container.tsx (1)
  • Container (1-15)
🔇 Additional comments (3)
components/card.tsx (1)

4-12: LGTM! Props interface and signature correctly updated.

The removal of the unused index prop from both the Props interface and component signature is correct and aligns with the PR objective of using stable keys instead of array indices.

app/protocols/page.tsx (2)

112-117: The CTA component correctly accepts the link and linkText props. The component's Props interface (lines 3-8 in components/cta.tsx) defines both properties, and they are properly used within the component—link is passed to the Next.js Link href attribute, and linkText renders as the button label. No issues found.


99-107: Good fix—using stable, unique values as React keys.

The change from key={index} to key={protocol.title} is correct. All protocol titles in the array are unique and hardcoded, making them suitable as stable keys for proper React reconciliation.

If protocol objects are ever extended with additional unique identifiers (like IDs fetched from an API or generated dynamically), consider using those as keys instead to future-proof against title changes or duplicates.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
components/card.tsx (1)

33-41: Consider reverting to index-only key for description lines.

The composite key ${item}-${index} introduces risk without solving a real problem:

  • Duplicate key risk: If the description contains duplicate lines (e.g., repeated text or multiple blank lines), you'll get duplicate keys and React warnings.
  • No instability issue here: These are static description lines derived from splitting a string—they won't dynamically reorder or change independently.
  • Index is appropriate: React recommends using index as key for static lists that won't reorder, which is exactly this use case.

The main stable key fix was correctly applied at the parent level (using protocol.title for Card components). For these internal description lines, reverting to key={index} would be more appropriate and eliminate the duplicate key risk.

🔎 Suggested fix
-            {description.split("\n").map((item, index) => {
+            {description.split("\n").map((item, idx) => {
               return (
-                <span key={`${item}-${index}`}>
+                <span key={idx}>
                 {item}
                 <br />
                </span>
               )
             })}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e483319 and 14cbe72.

📒 Files selected for processing (1)
  • components/card.tsx
🔇 Additional comments (1)
components/card.tsx (1)

4-11: LGTM! Clean removal of unused index prop.

The removal of the index prop from the component interface and signature is consistent and aligns with the parent page now using protocol.title as a stable key for Card components in the list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant