警告:列表中的每个 child 都应该有一个唯一的 "key" 属性。即使已经设置了密钥
Warning: Each child in a list should have a unique "key" prop. Even after setting the key already
我在 front-end 中使用 react,在后端使用 node、express 和 mongoose。
我已经在文件中设置了 key={uniqueid} 但我仍然收到错误。
这是完整的错误:
index.js:1 Warning: Each child in a list should have a unique "key" prop.
Check the render method of `ArticleCard`. See for more information.
in div (at ArticleCard.js:34)
in ArticleCard (at Blog.js:24)
in div (at Blog.js:22)
in div (at Blog.js:21)
in Blog (created by Context.Consumer)
in Route (at App.js:44)
in Switch (at App.js:38)
in AuthContextProvider (at App.js:35)
in Router (created by BrowserRouter)
in BrowserRouter (at App.js:34)
in div (at App.js:32)
in App (at src/index.js:9)
in StrictMode (at src/index.js:8)
index.js:1 Warning: Each child in a list should have a unique "key" prop.
Check the render method of `CreateArticle`. See for more information.
in option (at CreateArticle.js:92)
in CreateArticle (created by Context.Consumer)
in Route (at App.js:42)
in Switch (at App.js:38)
in AuthContextProvider (at App.js:35)
in Router (created by BrowserRouter)
in BrowserRouter (at App.js:34)
in div (at App.js:32)
in App (at src/index.js:9)
in StrictMode (at src/index.js:8)
这里是ArticleCard.js:
import React, { Component, useState, useEffect} from 'react';
import Cookies from 'js-cookie';
import '../components/CSS/ArticleCard.css'
import { Link, Redirect } from 'react-router-dom';
const axios = require('axios').default;
const ArticleCard = () => {
const [posts, setPosts] = useState({
postAll: [{}]
})
useEffect(() => {
axios.get('http://localhost:2000/apiEndpoint/READ')
.then(res => {
setPosts({ ...posts,
postAll: res.data
})
})
}, [])
const articles = posts.postAll.map(post => {
const uniqueID = post._id
return (
<div key={uniqueID} className='card'>
<h3>{post.title}</h3>
<hr/>
<h4>{post.body}</h4>
<Link className='button' to={`/blog/page/${uniqueID}`}>Open</Link>
</div>
)
})
return (
<div className='cardContainer'>
{
articles > 0 ? "NO" : articles
}
</div>
)
}
export default ArticleCard
这里是CreateArticle.js:
import { useState } from "react";
import React from 'react';
import axios from 'axios'
import '../CSS/CreateArticle.css'
const CreateArticle=()=>{
const newData={
title: '',
body:'',
category:'',
success:'',
fail:''
}
const [data, setData] = useState(newData);
const [response, setResponse] = useState(newData);
const [category,setCategory] = useState(['Fashion', 'Food', 'Travel', 'Music', 'Lifestyle', 'Fitness', 'DIY', 'Sports', 'Finance', 'Politics', 'Parenting'])
const handleSubmit=async (e)=>{
e.preventDefault()
await axios.post('http://localhost:2000/apiEndpoint/CREATE', {
title: data.title,
body: data.body,
category:data.category
},{withCredentials:true},{
headers: {
'Content-Type': 'application/json'
}})
.then(function (res) {
if(res.data==='Post Added'){
console.log('Success:',res)
setResponse({...response, title:'', body:'',category:'',success: "Post Sucessfully Added"})
}else if(res.data==='JWT authentication failed'){
setResponse({...response, title:'', body:'',category:'',fail: "You need to login before creating a new post"})
}else{
console.log('Erorr', res)
setResponse({...response, title:res.data.error.title, body:res.data.error.body,category:res.data.error.category,success:''})
}
})
}
const handleChange=(e)=>{
const {name,value}=e.target
setData({ ...data, [name]: value });
}
return(
<div className='ninetyPer'>
<div className='flexit'>
<h1>Create Post</h1>
{response.success?(<h5 className='success'>{response.success}</h5>):''}
{response.fail?(<h5 className='err'>{response.fail}</h5>):''}
<form onSubmit={handleSubmit}>
<div className='Container'>
<div className='inputField'>
<input name='title' onChange={handleChange} value={data.title} placeholder='Title'></input>
{response.title?(<h5 className="err">{response.title}</h5>):''}
</div>
<div className='bodyField'>
<textarea
name='body'
onChange={handleChange}
value={data.body}
placeholder='Write anything'
/>
{response.body?(<h5 className="err">{response.body}</h5>):''}
</div>
<div className='selectField'>
<select name='category' value={data.category} onChange={handleChange}>
<option value=''>~None Selected~</option>
{category.map(cat=>{
return(
<option value={cat}>{cat}</option>
)
})
}
</select>
{response.category?(<h5 className="err">{response.category}</h5>):''}
</div>
</div>
<button className='submitBtn'>Submit</button>
</form>
</div>
</div>
)
}
export default CreateArticle
如果您需要任何其他文件来查找问题,我会用它更新我的 post。
更新:
我检查了 console.log(uniqueID)。起初,它给了我 UNDEFINED 但另一次它给了我 ID。我不知道为什么一开始它有 UNDEFINED,即使我检查了数据库中的数据并且它们都有单独的唯一 ID。
我认为问题是 const uniqueID = post._id。您必须打印 (console.log(post._id)) 才能看到此值不为空或不重复。也在:
<select name='category' value={data.category} onChange={handleChange}>
<option value=''>~None Selected~</option>
{category.map(cat=>{
return(
<option value={cat}>{cat}</option>
)
})
}
您需要指定一个键值
<option key={[uniquevalue]} value={cat}>{cat}</option>
在 ArticleCard.js
中使用 console.log(uniqueID)
检查 id 是否有任何值或显示未定义。
如果值显示未定义,则尝试检查传递该 ID 的代码。
如果uniqueID
显示一些值那么可能有两种可能性
检查 ID 是否与其他 ID 不匹配,或者您是否使用任何删除 post 选项
如果在删除任何 post 后添加 post 时崩溃,则检查您是否正在增加 ID,如果是的话,ID 匹配项可能已经存在
文件ArticleCard.js
选项 1:
import React, { useState, useEffect, useMemo } from 'react';
import Cookies from 'js-cookie';
import '../components/CSS/ArticleCard.css'
import { Link, Redirect } from 'react-router-dom';
const axios = require('axios').default;
const ArticleCard = () => {
const [posts, setPosts] = useState({
postAll: [] // remove the empty object from the state initialization
});
useEffect(() => {
axios.get('http://localhost:2000/apiEndpoint/READ')
.then(res => {
setPosts({
...posts,
postAll: res.data
})
})
}, [])
/*
* check whether there are posts; if not, 'articles' will be null
* NOTE: useMemo aim is to avoid recalculating 'articles' at each re-render
* unless 'posts.postAll' has changed.
*/
const articles = useMemo(() => {
if (posts.postAll.length === 0) return null;
return posts.postAll.map(post => {
const uniqueID = post._id;
return (
<div key={uniqueID} className='card'>
<h3>{post.title}</h3>
<hr />
<h4>{post.body}</h4>
<Link className='button' to={`/blog/page/${uniqueID}`}>Open</Link>
</div>
);
});
}, [posts.postAll]);
return (
<div className='cardContainer'>
{articles ? articles : "NO"}
</div>
);
}
export default ArticleCard;
选项 2:去掉 'articles' const
import React, { useState, useEffect } from 'react';
import Cookies from 'js-cookie';
import '../components/CSS/ArticleCard.css'
import { Link, Redirect } from 'react-router-dom';
const axios = require('axios').default;
const ArticleCard = () => {
const [posts, setPosts] = useState({
postAll: [] // remove the empty object from the state initialization
});
useEffect(() => {
axios.get('http://localhost:2000/apiEndpoint/READ')
.then(res => {
setPosts({
...posts,
postAll: res.data
})
})
}, [])
return (
<div className='cardContainer'>
{posts.postAll.length === 0 ? "NO" : (
posts.postAll.map(post => {
const uniqueID = post._id;
return (
<div key={uniqueID} className='card'>
<h3>{post.title}</h3>
<hr />
<h4>{post.body}</h4>
<Link className='button' to={`/blog/page/${uniqueID}`}>Open</Link>
</div>
);
});
)
</div>
);
}
export default ArticleCard;
文件CreateArticle.js
...
<select name='category' value={data.category} onChange={handleChange}>
<option value=''>~None Selected~</option>
{category.map(cat=>{
return (
<option key='add_the_key_here' value={cat}>{cat}</option>
);
})}
</select>
...
我在 front-end 中使用 react,在后端使用 node、express 和 mongoose。
我已经在文件中设置了 key={uniqueid} 但我仍然收到错误。
这是完整的错误:
index.js:1 Warning: Each child in a list should have a unique "key" prop.
Check the render method of `ArticleCard`. See for more information.
in div (at ArticleCard.js:34)
in ArticleCard (at Blog.js:24)
in div (at Blog.js:22)
in div (at Blog.js:21)
in Blog (created by Context.Consumer)
in Route (at App.js:44)
in Switch (at App.js:38)
in AuthContextProvider (at App.js:35)
in Router (created by BrowserRouter)
in BrowserRouter (at App.js:34)
in div (at App.js:32)
in App (at src/index.js:9)
in StrictMode (at src/index.js:8)
index.js:1 Warning: Each child in a list should have a unique "key" prop.
Check the render method of `CreateArticle`. See for more information.
in option (at CreateArticle.js:92)
in CreateArticle (created by Context.Consumer)
in Route (at App.js:42)
in Switch (at App.js:38)
in AuthContextProvider (at App.js:35)
in Router (created by BrowserRouter)
in BrowserRouter (at App.js:34)
in div (at App.js:32)
in App (at src/index.js:9)
in StrictMode (at src/index.js:8)
这里是ArticleCard.js:
import React, { Component, useState, useEffect} from 'react';
import Cookies from 'js-cookie';
import '../components/CSS/ArticleCard.css'
import { Link, Redirect } from 'react-router-dom';
const axios = require('axios').default;
const ArticleCard = () => {
const [posts, setPosts] = useState({
postAll: [{}]
})
useEffect(() => {
axios.get('http://localhost:2000/apiEndpoint/READ')
.then(res => {
setPosts({ ...posts,
postAll: res.data
})
})
}, [])
const articles = posts.postAll.map(post => {
const uniqueID = post._id
return (
<div key={uniqueID} className='card'>
<h3>{post.title}</h3>
<hr/>
<h4>{post.body}</h4>
<Link className='button' to={`/blog/page/${uniqueID}`}>Open</Link>
</div>
)
})
return (
<div className='cardContainer'>
{
articles > 0 ? "NO" : articles
}
</div>
)
}
export default ArticleCard
这里是CreateArticle.js:
import { useState } from "react";
import React from 'react';
import axios from 'axios'
import '../CSS/CreateArticle.css'
const CreateArticle=()=>{
const newData={
title: '',
body:'',
category:'',
success:'',
fail:''
}
const [data, setData] = useState(newData);
const [response, setResponse] = useState(newData);
const [category,setCategory] = useState(['Fashion', 'Food', 'Travel', 'Music', 'Lifestyle', 'Fitness', 'DIY', 'Sports', 'Finance', 'Politics', 'Parenting'])
const handleSubmit=async (e)=>{
e.preventDefault()
await axios.post('http://localhost:2000/apiEndpoint/CREATE', {
title: data.title,
body: data.body,
category:data.category
},{withCredentials:true},{
headers: {
'Content-Type': 'application/json'
}})
.then(function (res) {
if(res.data==='Post Added'){
console.log('Success:',res)
setResponse({...response, title:'', body:'',category:'',success: "Post Sucessfully Added"})
}else if(res.data==='JWT authentication failed'){
setResponse({...response, title:'', body:'',category:'',fail: "You need to login before creating a new post"})
}else{
console.log('Erorr', res)
setResponse({...response, title:res.data.error.title, body:res.data.error.body,category:res.data.error.category,success:''})
}
})
}
const handleChange=(e)=>{
const {name,value}=e.target
setData({ ...data, [name]: value });
}
return(
<div className='ninetyPer'>
<div className='flexit'>
<h1>Create Post</h1>
{response.success?(<h5 className='success'>{response.success}</h5>):''}
{response.fail?(<h5 className='err'>{response.fail}</h5>):''}
<form onSubmit={handleSubmit}>
<div className='Container'>
<div className='inputField'>
<input name='title' onChange={handleChange} value={data.title} placeholder='Title'></input>
{response.title?(<h5 className="err">{response.title}</h5>):''}
</div>
<div className='bodyField'>
<textarea
name='body'
onChange={handleChange}
value={data.body}
placeholder='Write anything'
/>
{response.body?(<h5 className="err">{response.body}</h5>):''}
</div>
<div className='selectField'>
<select name='category' value={data.category} onChange={handleChange}>
<option value=''>~None Selected~</option>
{category.map(cat=>{
return(
<option value={cat}>{cat}</option>
)
})
}
</select>
{response.category?(<h5 className="err">{response.category}</h5>):''}
</div>
</div>
<button className='submitBtn'>Submit</button>
</form>
</div>
</div>
)
}
export default CreateArticle
如果您需要任何其他文件来查找问题,我会用它更新我的 post。
更新: 我检查了 console.log(uniqueID)。起初,它给了我 UNDEFINED 但另一次它给了我 ID。我不知道为什么一开始它有 UNDEFINED,即使我检查了数据库中的数据并且它们都有单独的唯一 ID。
我认为问题是 const uniqueID = post._id。您必须打印 (console.log(post._id)) 才能看到此值不为空或不重复。也在:
<select name='category' value={data.category} onChange={handleChange}>
<option value=''>~None Selected~</option>
{category.map(cat=>{
return(
<option value={cat}>{cat}</option>
)
})
}
您需要指定一个键值
<option key={[uniquevalue]} value={cat}>{cat}</option>
在 ArticleCard.js
中使用 console.log(uniqueID)
检查 id 是否有任何值或显示未定义。
如果值显示未定义,则尝试检查传递该 ID 的代码。
如果uniqueID
显示一些值那么可能有两种可能性
检查 ID 是否与其他 ID 不匹配,或者您是否使用任何删除 post 选项
如果在删除任何 post 后添加 post 时崩溃,则检查您是否正在增加 ID,如果是的话,ID 匹配项可能已经存在
文件ArticleCard.js
选项 1:
import React, { useState, useEffect, useMemo } from 'react';
import Cookies from 'js-cookie';
import '../components/CSS/ArticleCard.css'
import { Link, Redirect } from 'react-router-dom';
const axios = require('axios').default;
const ArticleCard = () => {
const [posts, setPosts] = useState({
postAll: [] // remove the empty object from the state initialization
});
useEffect(() => {
axios.get('http://localhost:2000/apiEndpoint/READ')
.then(res => {
setPosts({
...posts,
postAll: res.data
})
})
}, [])
/*
* check whether there are posts; if not, 'articles' will be null
* NOTE: useMemo aim is to avoid recalculating 'articles' at each re-render
* unless 'posts.postAll' has changed.
*/
const articles = useMemo(() => {
if (posts.postAll.length === 0) return null;
return posts.postAll.map(post => {
const uniqueID = post._id;
return (
<div key={uniqueID} className='card'>
<h3>{post.title}</h3>
<hr />
<h4>{post.body}</h4>
<Link className='button' to={`/blog/page/${uniqueID}`}>Open</Link>
</div>
);
});
}, [posts.postAll]);
return (
<div className='cardContainer'>
{articles ? articles : "NO"}
</div>
);
}
export default ArticleCard;
选项 2:去掉 'articles' const
import React, { useState, useEffect } from 'react';
import Cookies from 'js-cookie';
import '../components/CSS/ArticleCard.css'
import { Link, Redirect } from 'react-router-dom';
const axios = require('axios').default;
const ArticleCard = () => {
const [posts, setPosts] = useState({
postAll: [] // remove the empty object from the state initialization
});
useEffect(() => {
axios.get('http://localhost:2000/apiEndpoint/READ')
.then(res => {
setPosts({
...posts,
postAll: res.data
})
})
}, [])
return (
<div className='cardContainer'>
{posts.postAll.length === 0 ? "NO" : (
posts.postAll.map(post => {
const uniqueID = post._id;
return (
<div key={uniqueID} className='card'>
<h3>{post.title}</h3>
<hr />
<h4>{post.body}</h4>
<Link className='button' to={`/blog/page/${uniqueID}`}>Open</Link>
</div>
);
});
)
</div>
);
}
export default ArticleCard;
文件CreateArticle.js
...
<select name='category' value={data.category} onChange={handleChange}>
<option value=''>~None Selected~</option>
{category.map(cat=>{
return (
<option key='add_the_key_here' value={cat}>{cat}</option>
);
})}
</select>
...