reactjs 无法在使用React useEffect挂接刷新页面后将数据保留在localStorage上

fae0ux8s  于 2022-12-18  发布在  React
关注(0)|答案(1)|浏览(224)

我正在学习一个为菜谱构建前端项目的教程,但我无法复制持久化数据的行为(也就是说,如果我删除一个默认菜谱并添加一个新菜谱,它应该在页面刷新后反映相同的行为,而不是再次被默认菜谱填充)。我想对页面进行更改,并希望它在页面刷新后保持不变。
我使用React useEffect钩子和localStorage来实现这个目的。
所需的代码和截图张贴在下面。请添加您的任何输入。所有的建议是受欢迎的。谢谢。
CodeSandbox链接:https://codesandbox.io/s/github/ft76/NewNew CSS样式在这里没有反映出来,但是通过React添加的特性,比如AddRecipe按钮可以正常工作。
还有其他处理菜谱等的模块文件,我将排除它们,因为它们与当前的问题没有任何关系。代码如下:

import React, {useState, useEffect} from 'react';
import RecipeList from './RecipeList';
import '../css/app.css';
import { v4 as uuidv4 } from 'uuid';

export const RecipeContext = React.createContext()
const LOCAL_STORAGE_KEY = 'cookingWithReact.recipes';

function App() {
  const [recipes, setRecipes] = useState(sampleRecipes)

  useEffect(() => {
    const recipeJSON = localStorage.getItem(LOCAL_STORAGE_KEY);
    if (recipeJSON !== null) {
      setRecipes(JSON.parse(recipeJSON))
    }
  }, [])

  useEffect(() => {
    localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(recipes))
  }, [recipes])

  const recipeContextValue = {
    handleRecipeAdd,
    handleRecipeDelete
  }

  function handleRecipeAdd() {
    const newRecipe = {
      id: uuidv4(),
      name: 'New',
      servings: 1,
      cookTime: '1:00',
      instructions: 'Instructions',
      ingredients: [
        {id: uuidv4(), name: 'Name', amount: '1 Tbs'}
      ]
    }

    setRecipes([...recipes, newRecipe])
  }

  function handleRecipeDelete(id) {
    setRecipes(recipes.filter(recipe => recipe.id !== id))
  }

  return (
    <RecipeContext.Provider value={recipeContextValue}>
      <RecipeList recipes={recipes} />
    </RecipeContext.Provider>
  )
}

const sampleRecipes = [
  {
    id: 1,
    name: 'Plain Chicken',
    servings: 3,
    cookTime: '1:45',
    instructions: "1. Put salt on chicken.\n2. Put chicken in oven.\n3. Eat the chicken.",
    ingredients : [
      {
        id: 1,
        name: 'Chicken',
        amount: '2 pounds'
      },
      {
        id: 2,
        name: 'Salt',
        amount: '1 Tbs'
      }
    ]
  },
  {
    id: 2,
    name: 'Plain Pork',
    servings: 5,
    cookTime: '0:45',
    instructions: "1. Put paprika on pork.\n2. Put pork in oven.\n3. Eat the pork.",
    ingredients : [
      {
        id: 1,
        name: 'Pork',
        amount: '3 pounds'
      },
      {
        id: 2,
        name: 'Paprika',
        amount: '2 Tbs'
      }
    ]
  }
]

export default App;

所需屏幕截图如下:
默认屏幕:

删除一个默认配方并添加新配方后的屏幕:

刷新页面后的屏幕:

fhity93d

fhity93d1#

代码中的错误在于,您正在从constarray of objects中检索数据。
我已经用一个新的数组sampleRecipes2更改了sampleRecipes,它将检查本地存储是否为空,这部分是这样的。
可以使用任何array初始化sampleRecipes2

let sampleRecipes2 = [];
  let info = localStorage.getItem(LOCAL_STORAGE_KEY);
  if (info === null) {
    sampleRecipes2 = sampleRecipes;
  } else {
    sampleRecipes2 = JSON.parse(info);
  }

总的来说,这应该是你的App.js

import React, { useState, useEffect } from "react";
import RecipeList from "./RecipeList";
import "../css/app.css";
import { v4 as uuidv4 } from "uuid";

export const RecipeContext = React.createContext();
const LOCAL_STORAGE_KEY = "cookingWithReact.recipes";
function App() {
  let sampleRecipes2 = [];
  let info = localStorage.getItem(LOCAL_STORAGE_KEY);
  if (info === null) {
    sampleRecipes2 = sampleRecipes;
  } else {
    sampleRecipes2 = JSON.parse(info);
  }
  const [recipes, setRecipes] = useState(sampleRecipes2);
  useEffect(() => {
    localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(recipes));
  }, [recipes]);

  const recipeContextValue = {
    handleRecipeAdd,
    handleRecipeDelete
  };

  function handleRecipeAdd() {
    const newRecipe = {
      id: uuidv4(),
      name: "New",
      servings: 1,
      cookTime: "1:00",
      instructions: "Instructions",
      ingredients: [{ id: uuidv4(), name: "Name", amount: "1 Tbs" }]
    };

    setRecipes([...recipes, newRecipe]);
  }

  function handleRecipeDelete(id) {
    setRecipes(recipes.filter((recipe) => recipe.id !== id));
  }

  return (
    <RecipeContext.Provider value={recipeContextValue}>
      <RecipeList recipes={recipes} />
    </RecipeContext.Provider>
  );
}

const sampleRecipes = [
  {
    id: 1,
    name: "Plain Chicken",
    servings: 3,
    cookTime: "1:45",
    instructions:
      "1. Put salt on chicken.\n2. Put chicken in oven.\n3. Eat the chicken.",
    ingredients: [
      {
        id: 1,
        name: "Chicken",
        amount: "2 pounds"
      },
      {
        id: 2,
        name: "Salt",
        amount: "1 Tbs"
      }
    ]
  },
  {
    id: 2,
    name: "Plain Pork",
    servings: 5,
    cookTime: "0:45",
    instructions:
      "1. Put paprika on pork.\n2. Put pork in oven.\n3. Eat the pork.",
    ingredients: [
      {
        id: 1,
        name: "Pork",
        amount: "3 pounds"
      },
      {
        id: 2,
        name: "Paprika",
        amount: "2 Tbs"
      }
    ]
  }
];

export default App;

相关问题