刷新浏览器后显示 localStorage 中的收藏项 - Next.js 和 Typescript 项目

Posted

技术标签:

【中文标题】刷新浏览器后显示 localStorage 中的收藏项 - Next.js 和 Typescript 项目【英文标题】:Show fav items from localStorage after refresh browser - Next.js & Typescript project 【发布时间】:2022-01-21 06:57:58 【问题描述】:

我在 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;

【问题讨论】:

【参考方案1】:

我会根据你的问题将答案分成两部分。

    问题 - 将喜爱的电影存储到 localStorage 并在刷新页面后继续存储。

只是一些笔记

如果您使用addFav 方法的目的只是在localStorage 中切换最喜欢的电影,那么我认为您编写的业务逻辑太复杂了。我只是将它分成addFavremoveFav 方法,就是这样。
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]);

刷新页面后看不到收藏项的原因是favourites 变量在首次渲染Home 组件时始终设置为[]
const [favourites, setFavourites] = useState(
    JSON.parse(localStorage.getItem("favourites")) || []
);
我不会使用 电影标题 作为标识,因为您无法确定 API 响应中的密钥是唯一的。
    问题 - 首先列出最喜欢的人
我会亲自将过滤后的胶片阵列分成 2 个阵列

这里是https://codesandbox.io/s/strange-buck-voy0z?file=/src/App.js,最喜欢的电影在更改状态后立即排在第一位。

【讨论】:

以上是关于刷新浏览器后显示 localStorage 中的收藏项 - Next.js 和 Typescript 项目的主要内容,如果未能解决你的问题,请参考以下文章

解决vuex在页面刷新后数据丢失的问题

为啥读取 localStorage 值需要刷新页面才能显示由 jQuery 切换的 CSS 更改?

刷新后如何保持localStorage值?

(尚030)Vue_案例_存储数据(localStorage本地存储技术)

Angular 6:刷新后从localStorage获取令牌

存储数据后是不是有更好的方法从 localStorage 获取数据而不刷新/重新加载页面