blitz-js / blitz-js/next-superjson-plugin
Each child in a list should have a unique "key" prop.
- 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*/}
);
}
```
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