当用户注销或刷新页面时保存一个最喜欢的图标,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>
)
}
希望我的回答对您有所帮助。
大家早上好,我有一个按钮组件,可以控制用户是否想要收藏某样东西。一切正常,只要我不注销或刷新页面。
我觉得我知道如何实现它的逻辑,但我似乎不知道该怎么做。
我将收藏夹数组保存在本地存储以及我的数据库中。我将如何设置按钮的状态以在初始渲染时单击或不单击?
这是我的按钮的代码。
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>
)
}
希望我的回答对您有所帮助。