简体   繁体   English

React:如何避免 state 数组中的重复

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM