blitz-js / blitz-js/next-superjson-plugin

Each child in a list should have a unique "key" prop.

Open
#70 4 comments 6 reactions 0 assignees View on GitHub
bug
Dominant language
Rust
Stars
216
Forks
13
PR merge metrics
No merged PRs in 30d

Description

### Verify Next.js canary release

- [X] I verified that the issue exists in the latest Next.js canary release

### Describe the bug

I see the `Each child in a list should have a unique "key" prop.` warning message on the client side on multiple occassions, basically every
I figured out, that is, because I'm feeding the data to the react context api.

```jsx





```

Which components are affected?
Apparently the warning appears for every node where there are more than 1 children. That goes for normal components as well as plain jsx.

A full error log:
```text
hydration-error-info.js?7847:27 Warning: Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.
at div
at DocumentListContextProvider (webpack-internal:///(app-client)/./app/(index)/documents/document-list-context.tsx:25:11)
at WithSuperJSON (webpack-internal:///(app-client)/../../node_modules/next-superjson-plugin/dist/tools.js:153:55)
at SuperJSONComponent (webpack-internal:///(app-client)/../../node_modules/next-superjson-plugin/dist/client.js:18:24)
at ScrollAndFocusHandler (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:153:1)
at InnerLayoutRouter (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:195:11)
at RedirectErrorBoundary (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:361:9)
at RedirectBoundary (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:368:11)
at NotFoundBoundary (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:404:11)
at LoadingBoundary (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:317:11)
at ErrorBoundary (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/error-boundary.js:72:11)
at RenderFromTemplateContext (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/render-from-template-context.js:12:34)
at OuterLayoutRouter (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:23:11)
at div
at ScrollAndFocusHandler (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:153:1)
at InnerLayoutRouter (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:195:11)
at RedirectErrorBoundary (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:361:9)
at RedirectBoundary (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:368:11)
at NotFoundBoundary (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:404:11)
at LoadingBoundary (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:317:11)
at ErrorBoundary (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/error-boundary.js:72:11)
at RenderFromTemplateContext (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/render-from-template-context.js:12:34)
at OuterLayoutRouter (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:23:11)
at div
at div
at ScrollAndFocusHandler (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:153:1)
at InnerLayoutRouter (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:195:11)
at RedirectErrorBoundary (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:361:9)
at RedirectBoundary (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:368:11)
at NotFoundErrorBoundary (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:397:9)
at NotFoundBoundary (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:404:11)
at LoadingBoundary (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:317:11)
at ErrorBoundary (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/error-boundary.js:72:11)
at RenderFromTemplateContext (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/render-from-template-context.js:12:34)
at OuterLayoutRouter (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/layout-router.js:23:11)
at body
at html
at ReactDevOverlay (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/react-dev-overlay/internal/ReactDevOverlay.js:61:9)
at HotReload (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/react-dev-overlay/hot-reloader-client.js:20:11)
at Router (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/app-router.js:48:11)
at ErrorBoundaryHandler (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/error-boundary.js:59:9)
at ErrorBoundary (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/error-boundary.js:72:11)
at AppRouter (webpack-internal:///(app-client)/../../node_modules/next/dist/client/components/app-router.js:24:13)
at ServerRoot (webpack-internal:///(app-client)/../../node_modules/next/dist/client/app-index.js:147:11)
at RSCComponent
at Root (webpack-internal:///(app-client)/../../node_modules/next/dist/client/app-index.js:164:11)
```

I am using the `13.2.4-canary.8` version of next.

### Expected behavior

I expect to see no warning about missing unique key props

### Reproduction link

_No response_

### Version

0.5.6

### Config

```javascript
module.exports = {
reactStrictMode: true,
experimental: {
appDir: true,
swcPlugins: [
[ 'next-superjson-plugin', {} ]
]
},
async redirects() {
return [
{
source: '/',
destination: '/documents',
permanent: true,
},
]
},
transpilePackages: ['ui'],
};
```

### Additional context

**File**
`document-list-context.tsx`

```tsx
'use client';

import type { Dispatch, ReactNode } from 'react';
import { createContext, useReducer } from 'react';
import type { DocumentRevisionModel } from 'api-client';

export enum DocumentListContextActionKind {
SetDocuments = 'setDocuments',
AddDocument = 'addDocument',
}

export type DocumentListContextAction =
| {
type: DocumentListContextActionKind.SetDocuments;
documents: Array;
}
| {
type: DocumentListContextActionKind.AddDocument;
document: DocumentRevisionModel;
};

export interface DocumentListContextState {
documents: Array;
}

export interface DocumentListContextInterface extends DocumentListContextState {
documents: Array;
dispatch: Dispatch;
}

export const DocumentListContext = createContext({
documents: [],
dispatch: () => {
throw new Error('DocumentListContext not initialized');
},
});

interface DocumentListContextProviderProps {
children: ReactNode;
initialDocuments?: Array;
}

export function DocumentListContextProvider({
children,
initialDocuments = [],
}: DocumentListContextProviderProps) {
const [state, dispatch] = useReducer(
(state: DocumentListContextState, action: DocumentListContextAction) => {
switch (action.type) {
case DocumentListContextActionKind.SetDocuments:
return {
...state,
documents: action.documents,
};
case DocumentListContextActionKind.AddDocument:
return {
...state,
documents: [...state.documents, action.document],
};
default:
return state;
}
},
{
documents: initialDocuments,
},
);

return (

{children}

);
}
```

**File**
`page.tsx`

```tsx

export default async function Page() {
const apiConfiguration = createConfiguration({
baseServer: new ServerConfiguration('http://localhost:3001', {}),
});
const documentsApi = new DocumentsApi(apiConfiguration);
const documents = await documentsApi.documentsControllerList();

return (
({
...document,
}))}
data-superjson
>
{/* both will warn on this layer*/}



this div will not warn because there is only one child



);
}
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the supplied document-list-context.tsx and page.tsx snippets, then run the configured Next.js canary example with the next-superjson-plugin SWC plugin enabled. Compare rendering with one child versus multiple children and confirm that the warning is absent when the issue is fixed.

Written by the indexing model from the issue text.

Assessment

Tech stack
nextjs, react, typescript
Domain
tooling, web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.