从数组中删除信息时 React UseEffect 不更新

React UseEffect not updating when information is deleted from array

我一直在寻找帮助,因为我已经坚持了一段时间。我有一个与 Github API 交互的 MERN 堆栈应用程序。用户可以搜索 Github 用户并将他们保存到他们在应用程序上的个人资料中,一旦他们这样做,他们也会开始在 Github 上关注该用户。以同样的方式,用户可以从应用程序的个人资料中删除用户,这将在 Github 上取消关注同一用户。问题是,当我单击删除用户按钮时,它不会在浏览器上更新,除非我刷新页面然后我看到该用户已从已保存用户数组中删除。在 Profile.jsx 组件中,我呈现已保存用户的列表并从数据库中获取信息。在 SavedGithubUsersCard.jsx 组件中,我通过保存的用户数据进行映射以呈现用户的信息,例如姓名。在 DeleteButton.jsx 中,我在单击按钮时删除了特定的已保存用户。我的问题是我做错了什么?是道具更改未被触发还是 UseEffect 存在其他问题?

代码如下:

    import React, { useEffect, useContext } from 'react';
import swal from 'sweetalert';
import { AppContext } from '../context/AppContext';
import SavedGithubUsersCard from './SavedGithubUsersCard';
import axios from 'axios';

Profile.jsx
const Profile = () => {
  const {
    githubUserData, setGithubUserData
  } = useContext(AppContext);

  useEffect(() => {
    axios.get('/api/githubdata').then((res) => {
        setGithubUserData(res.data);
      })
      .catch((err) => {
        if (err) {
          swal('Error', 'Something went wrong.', 'error');
        }
      });
  }, [setGithubUserData]);

  return (
    <div className="profile-saved-users">
    <div className="githubUserData-cards">
    <h1 className="saved-users-header">Saved users</h1>
      {!githubUserData || githubUserData.length === 0 ? (
        <p className="no-saved-users-text">No saved users yet :(</p>
      ) : (
       <SavedGithubUsersCard githubUserData={githubUserData}/>
      )}
    </div>
    </div>
  );
};

export default Profile;



 import React from 'react';
import { Card, Button } from 'react-bootstrap';
import { Link } from 'react-router-dom';
import DeleteButton from './DeleteButton';

SavedGithubUsersCard.jsx

const SavedGithubUsersCard = ({githubUserData}) => {
    
    return (
        <>
           {githubUserData?.map(githubUserData => (
            <Card key={githubUserData._id} id="saved-users-card">
            <Card.Img
              variant="top"
              src={githubUserData.avatar_url}
              id="saved-users-card-image"
            />
            <Card.Body id="saved-users-card-information">
              <Card.Title
                id="saved-users-name"
                style={{ textAlign: 'center' }}
              >
                {githubUserData.name}
              </Card.Title>
              <Card.Subtitle
                id="saved-users-username"
                className="mb-2 text-muted"
                style={{ textAlign: 'center' }}
              >
                {githubUserData.login}
              </Card.Subtitle>
              <Card.Text id="saved-users-profile-url">
                Profile URL: {githubUserData.html_url}
              </Card.Text>
              <Link
                to={{ pathname: "githubUserData.html_url" }}
                target="_blank"
              >
                <Button
                  id="saved-users-profile-button"
                  variant="outline-primary"
                >
                  View profile
                </Button>
              </Link>
                <DeleteButton githubUserDataId={githubUserData._id} githubUserDataLogin= {githubUserData.login} />           
              </Card.Body>
          </Card>
             ))}
        </>
      );
    };

export default SavedGithubUsersCard

DeleteButton.jsx

    import React from 'react';
import { Button } from 'react-bootstrap';
import axios from 'axios';
import swal from 'sweetalert';

const DeleteButton = ({ githubUserDataLogin, githubUserDataId }) => {

  const handleRemove = async () => {
    try {
      fetch(`https://api.github.com/user/following/${githubUserDataLogin}`, {
        method: 'DELETE',
        headers: {
          Authorization: `token ${process.env.GITHUB_TOKEN}`
        }
      });
      await axios({
        method: 'DELETE',
        url: `/api/githubdata/${githubUserDataId}`,
        withCredentials: true
      });
      swal(
        'Removed from profile!',
        `You are no longer following ${githubUserDataLogin} on Github`,
        'success'
      );
    } catch (err) {
      swal('Error', 'Something went wrong.', 'error');
    }
  };

  return (
    <Button
      variant="outline-danger"
      style={{ marginLeft: 20 }}
      onClick={handleRemove}
      id="saved-users-delete-button"
    >
      Remove User
    </Button>
  );
};

export default DeleteButton;

AppContext.jsx

import React, { createContext, useState, useEffect } from 'react';
import axios from 'axios';

const AppContext = createContext();

    const AppContextProvider = ({ children }) => {
      const [currentUser, setCurrentUser] = useState(null);
      const [loading, setLoading] = useState(false);
      const [githubUserData, setGithubUserData] = useState([]);
      const user = sessionStorage.getItem('user');
    
      useEffect(() => {
        // incase user refreshes and context is cleared.
        if (user && !currentUser) {
          axios
            .get(`/api/users/me`, {
              withCredentials: true
            })
            .then(({ data }) => {
              setCurrentUser(data);
            })
            .catch((error) => console.error(error));
        }
      }, [currentUser, user]);
    
      return (
        <AppContext.Provider
          value={{ currentUser, setCurrentUser, loading, setLoading, githubUserData, setGithubUserData}}
        >
          {children}
        </AppContext.Provider>
      );
    };
    
    export { AppContext, AppContextProvider };

谢谢!

从我看到的你的代码来看,当你删除一个用户时,你在后端成功删除了他们,但也没有更新本地状态。

选项 1 - 重新获取用户列表并更新本地状态

const DeleteButton = ({ githubUserDataLogin, githubUserDataId }) => {
  const { setGithubUserData } = useContext(AppContext);

  const handleRemove = async () => {
    try {
      fetch(....);

      await axios(....);

      swal(....);

      const usersDataRes = await axios.get('/api/githubdata');
      setGithubUserData(usersDataRes.data);
    } catch (err) {
      swal('Error', 'Something went wrong.', 'error');
    }
  };

  return (
    ...
  );
};

选项 2 - 尝试手动同步本地状态

const DeleteButton = ({ githubUserDataLogin, githubUserDataId }) => {
  const { setGithubUserData } = useContext(AppContext);

  const handleRemove = async () => {
    try {
      fetch(....);

      await axios(....);

      swal(....);

      setGithubUserData(users => 
        users.filter(user => user._id !== githubUserDataId)
      );
    } catch (err) {
      swal('Error', 'Something went wrong.', 'error');
    }
  };

  return (
    ...
  );
};