刷新浏览器后显示 localStorage 中的收藏项 - Next.js & Typescript 项目
Show fav items from localStorage after refresh browser - Next.js & Typescript project
我正在 Next.js 和 Typescript 中做一个个人项目,我从 API 中获取一些数据。然后,我列出了一些项目。我想从中制作一个最喜欢的列表并将它们存储在 localStorage 中。代码工作正常,但如果我刷新浏览器,这些项目就会变得不受欢迎。但是,它们在 localStorage 中。我想在刷新后收藏这些项目。作为第二个问题,如果我也可以将最喜欢的项目放在其他项目之上,那就太棒了。我确定在这一行中我必须修复代码,但我不知道如何:
{favourites.includes(value.properties.title) || (localStorage.getItem('favourite') !== null) ?
这是完整的代码:
import { GetStaticProps, InferGetStaticPropsType } from "next";
import { FaHeart } from "react-icons/fa";
import { FaRegHeart } from "react-icons/fa";
import styles from '../styles/Home.module.css'
import { useState } from "react";
type Data = {
message: string;
result: [
{
properties: {
characters: string[];
planets: string[];
starships: string[];
vehicles: string[];
species: string[];
created: string;
edited: string;
producer: string;
title: string;
episode_id: number;
director: string;
release_date: string;
opening_crawl: string;
url: string;
};
}
];
};
export const getStaticProps: GetStaticProps<{ swapis: Data }> = async () => {
const res = await fetch("https://www.swapi.tech/api/films/");
const swapis: Data = await res.json();
return {
props: {
swapis
}
};
};
const Home = ({
swapis
}: InferGetStaticPropsType<typeof getStaticProps>) => {
console.log('swapis', swapis);
const [searchFilm, setSearchFilm] = useState<string>('');
const [favourites, setFavourites] = useState<Array<string>>([]);
const addFav = (props: any) => {
let array = favourites;
let addArray = true;
array.map((item: any, key: number) => {
if (item === props.value.properties.title) {
array.splice(key, 1);
addArray = false;
}
});
if (addArray) {
array.push(props.value.properties.title)
}
setFavourites([...array])
localStorage.setItem('favourites', JSON.stringify(favourites));
var storage = localStorage.getItem('favItem' + (props.value.properties.title) || '0')
if (storage == null) {
localStorage.setItem(('favItem' + (props.value.properties.title)), JSON.stringify(props))
} else {
localStorage.removeItem('favItem' + (props.value.properties.title))
}
}
return (
<>
<h1>List of Films</h1>
<div className={styles.containerTable}>
<input type="text" value={searchFilm} placeholder="Search films.." onChange={e => setSearchFilm(e.target.value)} />
</div>
{Object.entries(swapis?.result || {})
.filter(([key, value]) => {
if (!searchFilm) return true;
if (value.properties.title.toLowerCase().includes (searchFilm)) return true;
return false;
})
.map(([key, value]) => (
<table key={key} className={styles.containerTable}>
<tr className={styles.films}>
<td className={styles.films}>{value.properties.title} {favourites.includes(value.properties.title) || (localStorage.getItem('favourite') !== null) ? (
<FaHeart onClick={() => addFav({ value })} />
) : (
<FaRegHeart onClick={() => addFav({ value})} />
)}</td>
</tr>
</table>
))}
</>
);
};
export default Home;
我会根据你的问题分成两部分回答。
- 问题 - 将喜欢的电影存储到 localStorage 并在刷新页面后保留它们。
几个笔记
- 如果您使用
addFav
方法的目的只是切换 localStorage 中最喜欢的电影,那么我认为您编写的业务逻辑太复杂了。我只是将它分成 addFav
和 removeFav
方法,仅此而已。
const addFav = (id) => {
setFavourites([...favourites, id]);
};
const removeFav = (id) => {
setFavourites([...favourites.filter((found) => found !== id)]);
};
// Store in localstorage if favourites variable changes
useEffect(() => {
localStorage.setItem("favourites", JSON.stringify(favourites));
}, [favourites]);
- 您在刷新页面后看不到最喜欢的项目的原因是,当
Home
组件首次呈现时,favourites
变量始终设置为 []
。
const [favourites, setFavourites] = useState(
JSON.parse(localStorage.getItem("favourites")) || []
);
- 我不会使用 电影标题 作为标识,因为您无法确定密钥在 API 响应中是唯一的。
- 问题 - 先列出最喜欢的
- 我会亲自将过滤后的胶片数组分成 2 个数组
这里是 https://codesandbox.io/s/strange-buck-voy0z?file=/src/App.js 最喜欢的电影在更改状态后立即排在第一位。
我正在 Next.js 和 Typescript 中做一个个人项目,我从 API 中获取一些数据。然后,我列出了一些项目。我想从中制作一个最喜欢的列表并将它们存储在 localStorage 中。代码工作正常,但如果我刷新浏览器,这些项目就会变得不受欢迎。但是,它们在 localStorage 中。我想在刷新后收藏这些项目。作为第二个问题,如果我也可以将最喜欢的项目放在其他项目之上,那就太棒了。我确定在这一行中我必须修复代码,但我不知道如何:
{favourites.includes(value.properties.title) || (localStorage.getItem('favourite') !== null) ?
这是完整的代码:
import { GetStaticProps, InferGetStaticPropsType } from "next";
import { FaHeart } from "react-icons/fa";
import { FaRegHeart } from "react-icons/fa";
import styles from '../styles/Home.module.css'
import { useState } from "react";
type Data = {
message: string;
result: [
{
properties: {
characters: string[];
planets: string[];
starships: string[];
vehicles: string[];
species: string[];
created: string;
edited: string;
producer: string;
title: string;
episode_id: number;
director: string;
release_date: string;
opening_crawl: string;
url: string;
};
}
];
};
export const getStaticProps: GetStaticProps<{ swapis: Data }> = async () => {
const res = await fetch("https://www.swapi.tech/api/films/");
const swapis: Data = await res.json();
return {
props: {
swapis
}
};
};
const Home = ({
swapis
}: InferGetStaticPropsType<typeof getStaticProps>) => {
console.log('swapis', swapis);
const [searchFilm, setSearchFilm] = useState<string>('');
const [favourites, setFavourites] = useState<Array<string>>([]);
const addFav = (props: any) => {
let array = favourites;
let addArray = true;
array.map((item: any, key: number) => {
if (item === props.value.properties.title) {
array.splice(key, 1);
addArray = false;
}
});
if (addArray) {
array.push(props.value.properties.title)
}
setFavourites([...array])
localStorage.setItem('favourites', JSON.stringify(favourites));
var storage = localStorage.getItem('favItem' + (props.value.properties.title) || '0')
if (storage == null) {
localStorage.setItem(('favItem' + (props.value.properties.title)), JSON.stringify(props))
} else {
localStorage.removeItem('favItem' + (props.value.properties.title))
}
}
return (
<>
<h1>List of Films</h1>
<div className={styles.containerTable}>
<input type="text" value={searchFilm} placeholder="Search films.." onChange={e => setSearchFilm(e.target.value)} />
</div>
{Object.entries(swapis?.result || {})
.filter(([key, value]) => {
if (!searchFilm) return true;
if (value.properties.title.toLowerCase().includes (searchFilm)) return true;
return false;
})
.map(([key, value]) => (
<table key={key} className={styles.containerTable}>
<tr className={styles.films}>
<td className={styles.films}>{value.properties.title} {favourites.includes(value.properties.title) || (localStorage.getItem('favourite') !== null) ? (
<FaHeart onClick={() => addFav({ value })} />
) : (
<FaRegHeart onClick={() => addFav({ value})} />
)}</td>
</tr>
</table>
))}
</>
);
};
export default Home;
我会根据你的问题分成两部分回答。
- 问题 - 将喜欢的电影存储到 localStorage 并在刷新页面后保留它们。
几个笔记
- 如果您使用
addFav
方法的目的只是切换 localStorage 中最喜欢的电影,那么我认为您编写的业务逻辑太复杂了。我只是将它分成addFav
和removeFav
方法,仅此而已。
const addFav = (id) => {
setFavourites([...favourites, id]);
};
const removeFav = (id) => {
setFavourites([...favourites.filter((found) => found !== id)]);
};
// Store in localstorage if favourites variable changes
useEffect(() => {
localStorage.setItem("favourites", JSON.stringify(favourites));
}, [favourites]);
- 您在刷新页面后看不到最喜欢的项目的原因是,当
Home
组件首次呈现时,favourites
变量始终设置为[]
。
const [favourites, setFavourites] = useState(
JSON.parse(localStorage.getItem("favourites")) || []
);
- 我不会使用 电影标题 作为标识,因为您无法确定密钥在 API 响应中是唯一的。
- 问题 - 先列出最喜欢的
- 我会亲自将过滤后的胶片数组分成 2 个数组
这里是 https://codesandbox.io/s/strange-buck-voy0z?file=/src/App.js 最喜欢的电影在更改状态后立即排在第一位。