Like Counter正在更新每个伪帖子的状态



我是React的初学者,在做一个复制facebook用户界面的小项目时。我的伪数据如下:

dummy.js

export const users=[
{   'id':1,
'username':'Jane',
'profile_picture':'/assets/profilepictures/1.jpg',
'desc':'This is my first post',
'photos':'/assets/photos/a.jpg'
},
{   'id':2,
'username':'Max',
'profile_picture':'/assets/profilepictures/2.jpg',
'desc':'This is my first post',
'photos':'/assets/photos/b.jpg'
},
{
'id':3,
'username':'Mike',
'profile_picture':'/assets/profilepictures/3.jpg',
'desc':'This is my first post',
'photos':'/assets/photos/c.jpg'
},
{
'id':4,
'username':'Lucas',
'profile_picture':'/assets/profilepictures/4.jpg',
'desc':'This is my first post',
'photos':'/assets/photos/d.jpg'
},
{
'id':5,
'username':'Henry',
'profile_picture':'/assets/profilepictures/5.jpg',
'desc':'This is my first post',
'photos':'/assets/photos/e.jpg'
},
{
'id':6,
'username':'Hopper',
'profile_picture':'/assets/profilepictures/6.jpg',
'desc':'This is my first post',
'photos':'/assets/photos/f.jpg'
},
{
'id':7,
'username':'Dustin',
'profile_picture':'/assets/profilepictures/7.jpg',
'desc':'This is my first post',
'photos':'/assets/photos/g.jpg'
},
{
'id':8,
'username':'Will',
'profile_picture':'/assets/profilepictures/8.jpg',
'desc':'This is my first post',
'photos':'/assets/photos/h.jpg'
},
{
'id':9,
'username':'Erica',
'profile_picture':'/assets/profilepictures/9.jpg',
'desc':'This is my first post',
'photos':'/assets/photos/i.jpg'
},
{
'id':10,
'username':'Suzie',
'profile_picture':'/assets/profilepictures/10.jpg',
'desc':'This is my first post',
'photos':'/assets/photos/j.jpg'
},
{
'id':11,
'username':'Lyold',
'profile_picture':'/assets/profilepictures/11.jpg',
'desc':'This is my first post',
'photos':'/assets/photos/k.jpg'
},
{
'id':12,
'username':'Wanda',
'profile_picture':'/assets/profilepictures/12.jpg',
'desc':'This is my first post',
'photos':'/assets/photos/l.jpg'
},
{
'id':13,
'username':'Peter',
'profile_picture':'/assets/profilepictures/13.jpg',
'desc':'This is my first post',
'photos':'/assets/photos/m.jpg'
},
{
'id':14,
'username':'MJ',
'profile_picture':'/assets/profilepictures/14.jpg',
'desc':'This is my first post',
'photos':'/assets/photos/n.jpg'
}

]

我的React组件呈现了这些数据Centre.js

import React from 'react'
import '../styles/center.css'
import {users} from './dummy'
import {useState} from 'react'
import Button from '@mui/material/Button'
import FavoriteBorderIcon from '@mui/icons-material/FavoriteBorder';
import ChatBubbleOutlineIcon from '@mui/icons-material/ChatBubbleOutline';

export default function Centre() {
const [likes,setLikes]=useState(0)
const handleClick=(e)=>{
setLikes(likes+1)
}
return (
<div className='center'>
{users.map((e)=>(          
<div className='container' key={e.id}>
<img src={e.profile_picture} alt="pp"  id='profile-pic'/>
<span id='username'>{e.username}</span>
<p id='caption'>{e.desc}</p>
<img src={e.photos} alt="post" id='photos'/>
<div id='btm'>            
<FavoriteBorderIcon onClick={handleClick}/>
<span key={e.id}>{likes} people liked this</span>
<ChatBubbleOutlineIcon/>
</div>
</div>
))}
</div>
)
}

我实现了一个点赞计数器,当用户点击点赞按钮时显示点赞数量。问题是,当我点击一个特定帖子的赞按钮时,所有帖子的赞值都会更新。

我如何解决这个问题,以便当用户点击时,只有一个帖子的类似值得到更新。

每个条目的点赞数是相同的,因为您只定义了一个数字作为state。您可以使用长度为users的数组初始化状态,并使用map函数中的索引更新状态。如果您很好奇,可以通过记录状态onClick来了解它是如何工作的。

import React from 'react'
import '../styles/center.css'
import {users} from './dummy'
import {useState} from 'react'
import Button from '@mui/material/Button
import FavoriteBorderIcon from '@mui/icons-material/FavoriteBorder';
import ChatBubbleOutlineIcon from '@mui/icons-material/ChatBubbleOutline';

export default function Centre() {
const initLikes = new Array(users.length).fill(0);
const [likes,setLikes]=useState(initLikes)
const handleClick=(index)=>{
let tempLikes = likes
tempLikes[index] = tempLikes[index] + 1
setLikes(tempLikes)
}
return (
<div className='center'>
{users.map((e, index)=>(          
<div className='container' key={e.id}>
<img src={e.profile_picture} alt="pp"  id='profile-pic'/>
<span id='username'>{e.username}</span>
<p id='caption'>{e.desc}</p>
<img src={e.photos} alt="post" id='photos'/>
<div id='btm'>            
<FavoriteBorderIcon onClick={() => handleClick(index)}/>
<span key={e.id}>{likes[index]} people liked this</span>
<ChatBubbleOutlineIcon/>
</div>
</div>
))}
</div>
)
}

你在Center组件中有点赞,这是组件的中心状态,每当按下任何点赞按钮时,你都会更新它,所以在所有帖子中更新是很自然的,我认为你需要做的是向假人中的每个用户添加点赞数,然后在按下按钮时更新特定用户的点赞数,如果需要的话,我会尝试制作一个工作示例并与大家分享。

编辑:添加代码示例:

import React, { useState } from "react";
import { users } from "./dummy";
import FavoriteBorderIcon from "@mui/icons- 
material/FavoriteBorder";
import ChatBubbleOutlineIcon from "@mui/icons- 
material/ChatBubbleOutline";
export default function App() {
let [currentUsers, setCurrentUsers] = useState(users);
const handleClick = (id) => {
let user = currentUsers.find((user) => user.id === id);
user.likes++;
let updatedUsers = currentUsers.slice();
setCurrentUsers(updatedUsers);
// here I think you can write the updatedUsers to the file or DB.
};
return (
<div className="center">
{currentUsers.map((e) => (
<div className="container" key={e.id}>
<img src={e.profile_picture} alt="pp" id="profile-pic" />
<span id="username">{e.username}</span>
<p id="caption">{e.desc}</p>
<img src={e.photos} alt="post" id="photos" />
<div id="btm">
<FavoriteBorderIcon onClick={() => handleClick(e.id)} />
<span key={e.id}>{e.likes} people liked this</span>
<ChatBubbleOutlineIcon />
</div>
</div>
))}
</div>
);
}

我试着不使用setState,只通过id和增加点赞来找到用户,但这导致组件无法重新渲染,所以我不得不使用setState,也必须使用.sice,因为如果引用没有改变,那么组件也不会重新渲染。请注意,我编辑了伪数据文件,并将likes:0添加到每个对象中。

最新更新