React中的重复键,无法解决问题。遇到两个具有相同密钥的孩子

问题描述 投票:0回答:1

错误:

警告:使用相同的键5e0611d77833da1668feade1遇到了两个孩子。密钥应该是唯一的,以便组件在更新过程中保持其身份。非唯一键可能会导致子代重复和/或被忽略-该行为不受支持,并且可能在将来的版本中更改。

此图片上的https://prnt.sc/qgfymk我创建了2个博客。删除按钮工作正常。我正在通过axios将mongoose和MongoDB作为数据库发送到HTTP删除请求。

但是当我开始单击类似按钮时,请检查会发生什么。 https://prnt.sc/qgg32o它会删除我的其他博客文章,并复制一个具有相同名称和ID的文章。这里的问题是我有不同的ID,但是当我按LIKE按钮时,它又给了我另一个ID。

我将为您在增量和后端的前端和前端的PUT请求中提供代码,我真的不知道发生了什么。

controllers / blogs.js(后端)

blogsRouter.put('/:id', async (request, response, next) => {

  const body = request.body
  const blogs = {
    title:body.title,
    author: body.author,
    url:body.url,
    likes: body.likes
  }

  try {
    const updatedBlog = await Blog.findOneAndUpdate(request.params.id, blogs, {
      new: true
    })
    response.json(updatedBlog.toJSON())
  } catch (exception) {
    next(exception)
  }
})

App.js

import React, { useState, useEffect } from 'react';
import './App.css';
import Blog from './components/Blog';
import LoginForm from './components/LoginForm'
import BlogForm from './components/BlogForm'
import Notification from './components/Notification'

import loginService from './services/login';
import blogService from './services/blogs';


const App = () => {

  const [blogs, setBlogs] = useState([])
  const [user, setUser] = useState(null)
  const [username, setUsername] = useState('')
  const [password, setPassword] = useState('')
  const [errorMessage, setErrorMessage] = useState(null)

  // states for blog creation
  const [title, setTitle] = useState('')
  const [author, setAuthor] = useState('')
  const [url, setUrl] = useState('')

  useEffect(() => {
    console.log('effect')
    blogService
    .getAll()
    .then(response => {
      console.log('promise fulfiled')
      setBlogs(response.data)

    })
    .catch(error => {
      console.log('response', error.response)
      console.log('error')
    })
  }, [])

  useEffect(() => {
    const loggedUserJSON = window.localStorage.getItem('loggedBlogUser')
    if (loggedUserJSON) {
      const user = JSON.parse(loggedUserJSON)
      setUser(user)
      blogService.setToken(user.token)
    }
}, [])

  //put request
  ***const incrementLike = id => {
    const blog = blogs.find(b => b.id === id)
    console.log('blog id', blog)
    const voteLike = {...blog, likes: blog.likes + 1}

    blogService
    .update(id, voteLike)
    .then(returnedBlog => {
      setBlogs(blogs.map(blog => blog.id !== id ? blog : returnedBlog))
    })
    .catch(error => {
      setErrorMessage(
        `Blog was already removed from server`
      )
      setTimeout(() => {
        setErrorMessage(null)
      }, 5000)
      })
  }***

  //login
  const handleLogin = async (e) => {
    e.preventDefault()

    try {
      const user = await loginService.login({username, password})

      window.localStorage.setItem('loggedBlogUser', JSON.stringify(user))

      setUser(user)
      setUsername('')
      setPassword('')
      console.log('success')
    } catch (exception) {
        setErrorMessage('wrong credentials')
        setTimeout(() => {
          setErrorMessage(null)
        }, 5000)
        console.log('baaad')
    }
  }

  const deleteBlogId = (id) => {
    console.log('deleted blog')
    blogService
    .del(id)
    .then(response => {
      setBlogs(blogs.filter(blog => blog.id !== id))
    })
    .catch(error => {
      console.log(error.response);
    })
  }

  const handleCreateBlog = async (e) => {
    e.preventDefault()
    const newBlogs = {
      title: title,
      author: author,
      url: url,
      date: new Date()
    }

    blogService
    .create(newBlogs)
    .then(returnedBlog => {
      setBlogs(blogs.concat(returnedBlog))
      setTitle('')
      setAuthor('')
      setUrl('')
      setErrorMessage(`${author} created new blog with name ${title}`)
      setTimeout(() => {
        setErrorMessage(null)
      }, 5000)
    })
  }


  const loginForm = () => {

    return (
      <div>
        <Notification message={errorMessage}/>
        <div>
          <LoginForm 
            username={username}
            password={password}
            handleUsernameChange={({target}) => setUsername(target.value)}
            handlePasswordChange={({target}) => setPassword(target.value)}
            handleSubmit={handleLogin}
          />
        </div>
      </div>
    )
  }


  const handleTitleChange = (event) => {
    console.log(event.target.value)
    setTitle(event.target.value)
  }


  const blogForm = () => {
    return (
      <div>
        <BlogForm
          title={title}
          author={author}
          url={url}
          handleTitleChange={handleTitleChange}
          handleAuthorChange={({target}) => setAuthor(target.value)}
          handleUrlChange={({target}) => setUrl(target.value)}
          onSubmit={handleCreateBlog}
        />

      </div>
    )
  }

  const handleLogout = async () => {
    window.localStorage.clear()
    setUser(null)
  }


  const logout = () => {
    return (
    <div><button type="reset" onClick={handleLogout}>Logout</button></div>
    )}

  const blogList = () => {
    return (
      <div>
        <h2>Blogs</h2>
        <p>{user.name} logged in</p>
        {logout()}
        {blogs.map(blog => 
        <Blog 
        key={blog.id} 
        deleteBlog={() => deleteBlogId(blog.id)}
        blog={blog} 
        increment={() => incrementLike(blog.id)} />
        )}
      </div>
    )
  }

  return (
    <div className="App">

    {user === null ?

      loginForm() :
      <div>
        <Notification message={errorMessage}/>
        {blogForm()}
        {blogList()}
      </div> 
    }
    </div>
  );
}

export default App;

检查increasLikes函数。我认为有某种问题。 likies的按钮在名为Blog.js的组件中]

Blog.js

import React from 'react';


const Blog = ({blog, increment, deleteBlog}) => (
    <div>
        <button onClick={deleteBlog}>Delete</button> 
                {blog.title} 
                {blog.author} 
                {blog.likes} 
        <button onClick={increment}>Like</button>
    </div>
)

export default Blog

[错误:警告:遇到两个具有相同密钥5e0611d77833da1668feade1的孩子。密钥应该是唯一的,以便组件在更新过程中保持其身份。非唯一键可能会导致...

javascript node.js reactjs mongoose
1个回答
2
投票

虽然不应有2个具有相同ID的博客,但是您可以通过将键从blog.id替换为帖子的index来解决当前问题,

© www.soinside.com 2019 - 2024. All rights reserved.