#javascript #html #reactjs #react-context #react-key-index
#javascript #HTML #reactjs #реагировать-контекст #реагировать-ключ-индекс
Вопрос:
Я использую 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
Если вам потребуется какой-либо другой файл для поиска проблемы, я обновлю свой пост с его помощью.
Обновление: я проверил с помощью console.log (UniqueID). Сначала он дает мне UNDEFINED, но в другой раз он дает идентификатор. Я не знаю, почему именно сначала он не ОПРЕДЕЛЕН, хотя я проверил данные в БД, и все они имеют отдельные уникальные идентификаторы.
Комментарии:
1. это выглядит правильно.
_id
может быть, не определено?2. В вашем CreateArticle.js вы не устанавливаете
key
атрибут дляoption
файлов, сгенерированныхcategory.map( cat => { ... })
3. При использовании фрагментов стека рекомендуется нажать «Выполнить фрагмент кода», чтобы посмотреть, демонстрирует ли он что-нибудь интересное. Если нет, вам следует рассмотреть возможность использования кнопки форматирования кода (выглядит как
{}
) вместо этого.4. Спасибо, Секан, я исправил это, и эта ошибка исчезла, однако та, что в ArticleCard.js у меня все еще есть ошибка. 1 ошибка. осталось 1.
5. Вторая ошибка, вероятно, связана с тем, что вы извлекаете сообщения с помощью асинхронной операции и пытаетесь отобразить через
posts.postAll
whet, который он все еще содержит,[{}]
поэтомуpost._id
не определено. Я собираюсь опубликовать исправление в ответах, так как в комментариях нет места.![]()
Ответ №1:
Я думаю, что проблема в 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>
Комментарии:
1. Спасибо за ответ. Я проверил с помощью console.log (UniqueID). Сначала он дает мне UNDEFINED, но в другой раз он дает идентификатор. Я не знаю, почему именно сначала он не ОПРЕДЕЛЕН, хотя я проверил данные в БД, и все они имеют отдельные уникальные идентификаторы
2. Что касается другого в category.map, я присвоил ID тому же значению, что и строка в моем useState, поскольку все они уникальны.
Ответ №2:
Файл 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’
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>
...
Ответ №3:
ArticleCard.js
Используется console.log(uniqueID)
для проверки, имеет ли id какое-либо значение или оно показывает undefined.
Если значение отображается как неопределенное, попробуйте проверить код, из которого вы передаете этот идентификатор.
Если uniqueID
отображается какое-то значение, то может быть две возможности проверить, что идентификатор не совпадает с другим, или если вы используете какую-либо опцию удаления записи
Если он рухнет при добавлении сообщения после удаления любого сообщения, проверьте, увеличиваете ли вы идентификатор, если да, может быть вероятность, что совпадение идентификаторов уже существует
Комментарии:
1. Спасибо за ответ. Я проверил с помощью console.log (UniqueID). Сначала он дает мне UNDEFINED, но в другой раз он дает идентификатор. Я не знаю, почему именно сначала он не ОПРЕДЕЛЕН, хотя я проверил данные в БД, и все они имеют отдельные уникальные идентификаторы