如何从本地存储中删除已添加书签的元素



我正在制作一个为字符添加书签的应用程序。我必须将书签字符存储在本地存储中,这样当我刷新页面时,我就可以看到我的书签元素。

我的元素正确地保存到本地存储中,但当我刷新页面时,书签图标的状态没有保存(它被放回未填充的图标上,尽管元素仍在本地存储中(

第二个问题是,我不知道如何实现从本地存储中删除带有书签的元素。我想取消对特定元素的书签,并从本地存储中删除该元素。你可以在我的handleBookmarking功能中看到我是如何进行书签的,但我不知道如何进行书签和取消书签的双向功能。有什么想法吗?

这是代码:

CharactersList.js

import React, { useState } from "react";
import "./CharactersList.css";
import { RiBookmarkLine } from "react-icons/ri";
import { RiBookmarkFill } from "react-icons/ri";
const CharactersList = (props) => {
const [isLiked, setIsLiked] = useState([]);
const [favourites, setFavourites] = useState([]);
const saveToLocalStorage = (data) => {
localStorage.setItem("react-bookmarked-characters", JSON.stringify(data));
};
const handleBookmarking = (character) => {
if (isLiked.includes(character.id)) {
const newIsLiked = [...isLiked];
setIsLiked(newIsLiked);
} else {
setIsLiked([...isLiked, character.id]);
const newBookmarkedList = [...favourites, character];
setFavourites(newBookmarkedList);
saveToLocalStorage(newBookmarkedList);

}
};
const Bookmarked = ({ id }) => {
return isLiked.includes(id) ? <RiBookmarkFill /> : <RiBookmarkLine />;
};

return (
<>
{props.characters.map((character, index) => (
<div className="card-container" key={index}>
<img
src={`${character.thumbnail.path}/standard_fantastic.${character.thumbnail.extension}`}
alt="character"
className="image"
/>
<div className="info-container">
<p className="name">{character.name}</p>
<div
className="icon"
onClick={() => {
handleBookmarking(character);
}}
>
<Bookmarked id={character.id} />
</div>
</div>
</div>
))}
</>
);
};
export default CharactersList;

App.js因此,在App.js中,我调用了两个字符列表,一个是搜索输入为空时(显示所有书签元素(,另一个是正在搜索时(显示全部元素(。

const App = () => {
const [characters, setCharacters] = useState([]);
const [search, setSearch] = useState("");
const [favourites, setFavourites] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const [characterPerPage] = useState(20);
const getCharactersRequest = async () => {
const url = `https://gateway.marvel.com/v1/public/characters?nameStartsWith=${search}&ts=1&apikey=&hash=`; 
const response = await fetch(url);
const responseJSON = await response.json();
if (responseJSON.data) {
setCharacters(responseJSON.data.results);
}
};
useEffect(() => {
getCharactersRequest(search);
}, [search]);
useEffect(() => {
const bookMarkedData = JSON.parse(
localStorage.getItem("react-bookmarked-characters")
);
if (bookMarkedData) {
setFavourites(bookMarkedData);
}
}, [search]);
// Get 20 posts
const indexOfLastCharacter = currentPage * characterPerPage;
const indexOfFirstCharacter = indexOfLastCharacter - characterPerPage;
const slicedFavourites = favourites.slice(
indexOfFirstCharacter,
indexOfLastCharacter
);
return (
<div>
<div className="heading-container">
<SearchBarHeading heading={"MARVEL CHARACTERS"} />
<SearchBar search={search} setSearch={setSearch} />
</div>
<div className="cards-container">
{search === "" ? (
<CharactersList characters={slicedFavourites} />
) : (
<CharactersList characters={characters} />
)}
</div>
</div>
);
};
export default App;

您可以使用此函数。

若要添加,isAdd应为true。否则就鞭打。

const handleBookmark = (character, isAdd) => {
data = JSON.parse(localStorage.getItem("react-bookmarked-characters"));
if(isAdd){
//add to bookmark
data = [...data, character];
}else{
//remove from bookmark
data = data.filter(item => item.id !== character.id);
}
localStorage.setItem("react-bookmarked-characters", JSON.Stringify(data));
}

以下是我将如何解决它。

首先要做的是读取保存的书签,并将它们设置为组件的初始状态。

然后,我会使用React.useEffect来保持书签的状态,只要状态发生变化。

最后,我会稍微清理一下onClick处理程序,以处理书签ID的切换。

import React, { useState } from 'react';
import './CharactersList.css';
import { RiBookmarkLine } from 'react-icons/ri';
import { RiBookmarkFill } from 'react-icons/ri';
const StorageKey = 'react-bookmarked-characters';
const CharactersList = (props) => {
const initialState = JSON.parse(window.localStorage.getItem(StorageKey)) ?? [];
const [bookmarks, setBookmarks] = useState(initialState);
React.useEffect(() => {
window.localStorage.setItem(StorageKey, JSON.stringify(bookmarks));
}, [bookmarks]);
const handleLikeChange = (character) => {
setBookmarks((prevBookmarks) => {
if (prevBookmarks.includes.character.id) {
return prevBookmarks.filter((id) => id !== character.id);
}
return [...prevBookmarks, character.id];
});
};
return props.characters.map((character) => (
<Character
key={character.index}
character={character}
bookmarked={bookmarks.includes(character.id)}
onToggleBookmark={handleLikeChange}
/>
));
};
const Character = ({ character, bookmarked, onToggleBookmark }) => {
const handleClick = () => onToggleBookmark(character);
return (
<div className="card-container" key={character.index}>
<img
src={`${character.thumbnail.path}/standard_fantastic.${character.thumbnail.extension}`}
alt="character"
className="image"
/>
<div className="info-container">
<p className="name">{character.name}</p>
<div className="icon" onClick={handleClick}>
{bookmarked ? <RiBookmarkFill /> : <RiBookmarkLine />}
</div>
</div>
</div>
);
};
export default CharactersList;

最新更新