当用户注销或刷新页面时保存一个最喜欢的图标,react,mern stack

Save a favorite icon when a user logs out or refreshes the page, react, mern stack

大家早上好,我有一个按钮组件,可以控制用户是否想要收藏某样东西。一切正常,只要我不注销或刷新页面。

我觉得我知道如何实现它的逻辑,但我似乎不知道该怎么做。

我将收藏夹数组保存在本地存储以及我的数据库中。我将如何设置按钮的状态以在初始渲染时单击或不单击?

这是我的按钮的代码。

export default function FavoriteButton({
  _id,
  title,
  artist,
  rating,
  genre,
  description,
}) {
  //state for favorites
  const [click, handleClick] = React.useState(false);

  const [favorite, setFavorite] = React.useState([]);

  //get favorites

  const fetchData = async () => {
    const result = await axios.get(
      "http://localhost:5000/favorite/get",
      authToken
    );

    setFavorite(result);
  };

  React.useEffect(() => {
    fetchData();
  }, []);

  //add favorites
  const addFavorites = () => {
    const favorites = {
      userId: _id,
      title,
      artist,
      rating,
      genre,
      description,
    };

    axios
      .post("http://localhost:5000/favorite/add", favorites, authToken)
      .then((response) => {
        setFavorite(response);
      });

    fetchData();
    localStorage.setItem("favorite", JSON.stringify(favorite));

    handleClick(true);
  };

  // delete favorite

  const deleteFavorite = async () => {
   await axios.delete("http://localhost:5000/favorite/delete", {
      data: { title: title },
      authToken,
    });

    handleClick(false);
  };

  const classes = buttonStyles();

  return (
    <div>
      {click === false ? (
        <IconButton onClick={addFavorites} className={classes.favoriteOff}>
          {" "}
          <StarOutlineIcon className={classes.favoriteGrey} />{" "}
        </IconButton>
      ) : (
        <IconButton onClick={deleteFavorite} className={classes.favoriteOn}>
          {" "}
          <StarRateIcon className={classes.favoriteYellow} />
        </IconButton>
      )}
    </div>
  );
}

我正在映射另一个组件中的数据并在那里显示按钮。

我在这里添加了 parent 组件

export default function ShowRecords() {
  const classes = recordFormStyles();
  const url = " http://localhost:5000/record";

  //get userData state to use in useEffect

  //set state for showing records in database and opening/closing modals

  const [newRecords, newRecordData] = React.useState([]);

  const [editOpen, handleEditModal] = React.useState(false);

  const [addModalOpen, handleAddModal] = React.useState(false);

  //set state for edit records

  const [title, setTitle] = React.useState("");

  const [artist, setArtist] = React.useState("");

  const [rating, setRating] = React.useState("");

  const [genre, setGenre] = React.useState("");

  const [description, setDescription] = React.useState("");

  const [userId, setUserId] = React.useState("");

  //set state for favorite icon

  //functions to control state

  const handleAddModalOpen = () => {
    handleAddModal(true);
  };

  const handleCloseAddModal = () => {
    handleAddModal(false);
  };

  const handleIsEditModalClose = () => {
    handleEditModal();
  };

  //fetch record data

  const fetchData = async () => {
    const result = await axios.get(
      "http://localhost:5000/record/get",
      authToken
    );
    newRecordData(result.data);
  };

  React.useEffect(() => {
    fetchData();
  }, []);

  // delete records

  const deleteRecord = async (_id) => {
    const deleteRecords = {
      _id: _id,
    };

    await axios
      .delete("http://localhost:5000/record/" + _id, deleteRecords)
      .then((result) => {
        const refresh = newRecords.filter((result) => result._id !== _id);
        newRecordData(refresh);
      });
  };

  //functions for controlling edit record state

  const editRecord = (_id, title, artist, rating, genre, description) => {
    setUserId(_id);
    setTitle(title);
    setArtist(artist);
    setRating(rating);
    setGenre(genre);
    setDescription(description);
    handleEditModal(true);

    console.log(title);
  };

  //functions for setting favorite state and color and post request to add favorite

  return (
    <div>
      {/* set props */}

      <Favorites />
      <AddRecord
        isAddModalOpen={addModalOpen}
        handleIsAddModalClose={handleCloseAddModal}
        addNewRecords={newRecords}
        handleIsAddModalOpen={handleAddModal}
        refreshRecordData={newRecordData}
      />
      <EditRecords
        editModalOpen={editOpen}
        handleCloseEditModal={handleIsEditModalClose}
        editUserId={userId}
        editTitle={title}
        editArtist={artist}
        editRating={rating}
        editGenre={genre}
        editDescription={description}
        editTitleState={setTitle}
        editArtistState={setArtist}
        editRatingState={setRating}
        editGenreState={setGenre}
        editDescriptionState={setDescription}
        editUrl={url}
        editFetchData={fetchData}
        editNewRecordData={newRecordData}
      />
      <Button
        className={classes.addButton}
        onClick={() => handleAddModalOpen(true)}
      >
        Add Record
      </Button>

      <div className={classes.cardsContainer}>
        <Grid container spacing={10} style={{ padding: "24px" }}>
          {newRecords.length > 0 &&
            newRecords.map((element) => (
              <Grid key={element._id} item xs={12} sm={6} md={4} lg={4} xl={2}>
                <Card className={classes.root}>
                  <CardContent>
                    <>
                      <FavoriteButtonRecord
                        key={element._id}
                        title={element.title}
                        artist={element.artist}
                        rating={element.rating}
                        genre={element.genre}
                        description={element.description}
                      />
                    </>
                    <Typography gutterBottom variant="h6">
                      {element.title}
                    </Typography>
                    <Typography variant="body2" color="inherit" component="p">
                      Artist: {element.artist}
                    </Typography>
                    <Typography variant="body2" color="inherit" component="p">
                      Label: {element.rating}
                    </Typography>
                    <Typography variant="body2" color="inherit" component="p">
                      Genre: {element.genre}
                    </Typography>
                    <Typography variant="body2" color="inherit" component="p">
                      Description: {element.description}
                    </Typography>
                  </CardContent>

                  <CardActions>
                    <Button
                      onClick={() =>
                        editRecord(
                          element._id,
                          element.title,
                          element.artist,
                          element.rating,
                          element.genre,
                          element.description
                        )
                      }
                      size="small"
                      color="inherit"
                      className = {classes.button}
                    >
                      Edit
                    </Button>
                    <Button
                      onClick={() =>
                        deleteRecord(
                          element._id,
                          element.title,
                          element.artist,
                          element.rating,
                          element.genre,
                          element.description
                        )
                      }
                      size="small"
                      color="inherit"
                      className = {classes.button}
                    >
                      Delete
                    </Button>
                  </CardActions>
                </Card>
              </Grid>
            ))}
        </Grid>
      </div>
    </div>
  );
}

如果我还需要显示该代码,请告诉我。提前致谢!

我可以帮你。

首先,您应该做一些事情,不要在收藏按钮组件本身中处理更新。传入来自 parent 组件的处理程序,这些处理程序将更新状态并使用来自 parent 组件的数据在 props.

我将分享一个例子,这会让事情更清楚。 我们会用UserCard组件制作一个UserList,包括标记用户为收藏或标记为不喜欢。

export default function UserList() {
  const [users, setUsers] = useState([]);

  const getUsers = async () => {
    const result = await axios.get('/api/users');
    setUsers(result.data);
  };

  useEffect(() => {
    getUsers();
  });

  const markUserFavourite = async(userId) => {
    const updatedUser = await axios.post('/api/user/favourite', {userId});
    const otherUsers = users.filter(elem => elem._id !== userId);
    setUsers([...otherUsers, updatedUser]);
  };

  const removeUserFavourite = async(userId) => {
    const updatedUser = await axios.post('/api/user/favourite/remove', {userId});
    const otherUsers = users.filter(elem => elem._id !== userId);
    setUsers([...otherUsers, updatedUser]);
  };

  return (
    <div>
      {users.map(user => (
        <UserCard user={user} markFavourite={markUserFavourite} 
          removeFavourite={removeUserFavourite} />
      ))}
    </div>
  )
}

还有,这里是UserCard,只显示用户的详细信息

export default function UserCard(props) {
  const {user, markFavourite, removeFavourite} = props;
  const {name, _id, email, isFavorite} = user;
  return (
    <div>
      Name: {name}
      Email: {email}
      {isFavorite? 
        <button type="button" onClick={removeFavourite(_id)}> Remove Favorite </button> :
        <button type="button" onClick={markFavourite(_id)}> Mark Favorite </button>
      }
    </div>
  )
}

希望我的回答对您有所帮助。