[英]React: How to avoid duplication in a state array
I am making MERN social media app.我正在制作 MERN 社交媒体应用程序。
I want to show all the friends of the current user in a list in SideBar.jsx.我想在 SideBar.jsx 的列表中显示当前用户的所有朋友。
Home.jsx (parent of Sidebar.jsx) Home.jsx(Sidebar.jsx 的父级)
import React, { Component } from "react";
import { Person } from "@material-ui/icons";
import Topbar from "../../components/topbar/Topbar";
import Sidebar from "../../components/sidebar/Sidebar";
import Feed from "../../components/feed/Feed";
import Rightbar from "../../components/rightbar/Rightbar";
import "./home.css";
export default function Home() {
return (
<>
<Topbar />
<div className="homeContainer">
<Sidebar />
<Feed />
<Rightbar />
</div>
</>
);
}
SideBar.jsx侧边栏.jsx
import "./sidebar.css";
import React, { Component, useContext, useState } from "react";
...
import { axiosInstance } from "../../config";
export default function Sidebar() {
const { user } = useContext(AuthContext);
const [followings, setFollowings] = useState([]);
const followingsList = user.followings;
useEffect(() => {
const fetchFollowings = async () => {
followingsList.map(async (id) => {
try {
const theUser = await axiosInstance.get(`/users?userId=${id}`);
if (followings.includes(theUser.data)) {
} else {
setFollowings((prev) => [...prev, theUser.data]);
}
} catch (error) {
console.log(error);
}
});
};
fetchFollowings();
}, [user]);
return (
<div className="sidebar">
.....
<ul className="sidebarFriendList">
{followings.map((u) => (
<CloseFriend key={u._id} user={u} />
))}
</ul>
</div>
</div>
);
}
For example, in this case, in the state "followings", there are 2 user objects.例如,在这种情况下,在 state “followings”中,有 2 个用户对象。
So, the line所以,线
followings.map((u) => (...
should only show 2 entries.应该只显示 2 个条目。
However, the result is below.但是,结果如下。
As you can see, it is showing each friend twice.如您所见,它向每个朋友展示了两次。 I tired to check if a user object already exists in followings by doing
我厌倦了通过以下方式检查用户 object 是否已经存在
if (followings.includes(theUser.data)) {
} else {
setFollowings((prev) => [...prev, theUser.data]);
}
But this is not working.但这不起作用。
How can I make sure that it only shows each user once?如何确保它只显示每个用户一次?
I want it to be like this我希望它是这样的
Any help would be greatly appreciated.任何帮助将不胜感激。 thank you
谢谢你
When you are using the .map
function with async/await
Promise.all
usually always does the trick.当您使用
.map
function 和async/await
Promise.all
,通常总是可以解决问题。 Instead of pushing the state on every iteration you collect the followers list and set the state when all your fetching is done.不是在每次迭代时推送 state,而是收集关注者列表并在所有获取完成后设置 state。 I did not test it yet, but I hope it works.
我还没有测试它,但我希望它有效。
const followingsList = user.followings;
useEffect(() => {
const fetchFollowings = async () => {
const list = await Promise.all(followingsList.map(async (id) => (
await axios.get('/user?userId=' + id);
)));
setFollowers(list);
};
fetchFollowings();
}, [user]);
Note: let me know if it works, if not I'll do a little sandbox on my own注意:让我知道它是否有效,否则我会自己做一个小沙箱
This is happening because it seems that your useEffect
method is being fired two times (probably because you are using React.StrictMode
) and you are setting the state inside the .map
method (that is not good because you trigger a new render each time you call the setState
).发生这种情况是因为您的
useEffect
方法似乎被触发了两次(可能是因为您正在使用React.StrictMode
)并且您在.map
方法中设置 state (这不好,因为您每次都会触发新的渲染调用setState
)。
What I would recommend you to do, is to remove the setState
from the .map
method and just set the new state after you format your data.我建议您做的是从
.map
方法中删除setState
,并在格式化数据后设置新的 state 。 So it would be something like this:所以它会是这样的:
const newFollowings = followingsList.map(async (id) => {
try {
const theUser = await axiosInstance.get(`/users?userId=${id}`);
return theUser.data;
} catch (error) {
console.log(error);
}
});
setFollowings(newFollowings);
Probably you would have to add a filtering to the array in case there are some errors (because on errors the mapped value would be undefined
):如果出现一些错误,您可能必须向数组添加过滤器(因为错误时映射的值将是
undefined
):
.filter(data => data);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.