2

I'm making a recipe box project, I have a recipe state that has an array of recipe objects.

I use the saveToLocal function to save the current state into local storage like this:

 saveToLocal = () => {
 const local = this.state.recipe;
 localStorage.setItem("recipe", JSON.stringify(local));
}

and pass it back to functions that add, edit or delete new recipe like this

 addNewRecipe = (newRecipe) => {
  this.setState({
  recipe: [...this.state.recipe,newRecipe]
  }, this.saveToLocal);
}

 editRecipe = (recipe) => {
   let selectedRecipe =this.state.recipe.find(obj=>obj.count==recipe.count)
   let editedRecipe = Object.assign(selectedRecipe,recipe);
   this.setState(Object.assign(this.state.recipe,editedRecipe),this.saveToLocal)
}

deleteRecipe = (recipe) => {
  let arr = this.state.recipe.filter(obj => obj.count !== recipe.count);
}

However this does not work as I refresh the app, but when I check the local storage inside the inspect tool the localstorage still has recipe data. What is the way to fix this?

Thank you

4
  • Where do you get items again from localStorage? When you refresh your app you are losing your state. Commented May 9, 2018 at 22:37
  • What do you want to happen? Commented May 9, 2018 at 22:38
  • I want to save the recipe on refresh Commented May 9, 2018 at 22:45
  • Save on refresh? Save from where and where to? Commented May 9, 2018 at 22:48

3 Answers 3

3

Saving to local storage and getting from local storage are 2 different methods.

localStorage.setItem(‘recipe’, JSON.stringify(this.state.recipe)

const recipe = localStorage.getItem(‘recipe’)

this.setState({...recipe})

You don’t need to create a saveToLocal method

Sign up to request clarification or add additional context in comments.

Comments

2

If I understand right, you want to get saved recipe on refresh. You should use componentDidMount and get the recipe from localStorage, then set your state according to this.

componentDidMount() {
    const recipe = JSON.parse( localStorage.getItem( "recipe" ) );
    this.setState( { recipe } );
}

You can check for recipe and conditionally render your component:

render() {
    if( !this.state.recipe.length ) {
        return <p>No recipe</p>;
        // or you can use a spinner here
    }
    return { how you handle your recipe here, map it etc. }
}

4 Comments

Since the OP is using setState, shouldn't this be inside componentDidUpdate? (not didMount). Also they are already updating the state before setting the localStorage so there is no need to set the state once again here - that would unnecessarily cause the component to re-render twice.
@TPHughes, I understood and assumed that OP wants to populate state after refreshing app. After refresh there is no state but persistent info on localStorage. So state can be populated in componenetDidMount once app started or refreshed. componentDidMount runs after component mounts for the first time, not every time when state changes. It is a good place to get remote data once app started.
Ah yes, your completely right. I misread it myself - the issue being that he wants to retrieve it only when refreshing. That's good info, and my apologies.
No need to apology :)
1

You can then use localStorage.getItem("recipe") to retrieve it. Do a console log for that inside your render function and check your browser's JS Console.

render() {
   console.log('recipe is', localStorage.getItem("recipe"))
}

Your localStorage will stay on disk until you clear the cache.

2 Comments

Yeah it still logs out the data from localStorage but I don't know how to use them to display in the app
Just assign localStorage.getItem("recipe") to a variable. You are already setting the state before sending to localStorage, so you could retrieve it using this.state.recipe, but otherwise calling let foo = JSON.parse(localStorage.getItem("recipe")) anywhere in the render() method would allow you to use the recipe object as foo. JSON.parse() will simply take the JSON string and convert it to an object for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.