2017-01-25 2 views
0

Когда я запускаю этот код, я получаю группу панелей начальной загрузки для каждого элемента рецепта внутри локального хранилища. Когда я пытаюсь удалить рецепт, иногда правильный рецепт удаляется, а иногда нет. Консоль показывает, что правильный рецепт удаляется из локального хранилища, но по какой-то причине, когда компонент приложения сбрасывает свое состояние, неправильный рецепт удаляется. Я заметил, что если я попытаюсь удалить рецепты снизу вверх, это сработает. Но если я нажму на первый рецепт, нижний рецепт будет удален.Реакция: состояние настройки на основе локального хранилища

Я знаю, что это простое решение, но мне нужна свежая перспектива. Всем спасибо! Кроме того, извините отсутствие отступов в коде - переполнение стека не был слишком дружен с расстоянием

class App extends Component { 
    constructor() { 
    super(); 
    this.deleteRecipe = this.deleteRecipe.bind(this) 
    this.state = { 
    recipeData: JSON.parse(localStorage.getItem('recipeData')) 
} 
} 

deleteRecipe() { 
this.setState({recipeData: JSON.parse(localStorage.getItem('recipeData'))}) 
} 

render() { 
return (
    <div className="App"> 
    <div className="App-header"> 
     <img src={logo} className="App-logo" alt="logo" /> 
     <h2>Welcome to React Recipe Box!</h2> 
    </div> 

    <div className="container"> 
     {this.state.recipeData.map(recipe => { 
     return (
     <Recipe name={recipe.name} ingredients={recipe.ingredients} deleteRecipe={this.deleteRecipe}/> 
     ) 
     })} 
    </div> 
    </div> 
); 
} 
} 

class Recipe extends Component { 
constructor() { 
super(); 
    this.onDeleteRecipe = this.onDeleteRecipe.bind(this) 
} 

componentWillMount(){ //set state when component is about to mount 
this.state = { 
    name: this.props.name, 
    ingredients: this.props.ingredients, 

} 
} 

onDeleteRecipe() { 
var recipeList = JSON.parse(localStorage.getItem('recipeData')); 
for(var i = 0; i < recipeList.length; i++) { 
    if(recipeList[i].name === this.state.name) { 
    recipeList.splice(i, 1); 
    console.log("Deleted " + this.state.name, recipeList); 
    localStorage.removeItem('recipeData'); 
    localStorage.setItem('recipeData', JSON.stringify(recipeList)); 

    this.props.deleteRecipe(); 
    } 
} 

} 

render() { 
return (
<div> 
    <div className="panel-group"> 
    <div className="panel panel-primary"> 
     <div className="panel-heading"> 
     <h2 className="panel-title"> 
      <a data-toggle="collapse" data-target={'#' + (this.state.name).replace(/\s/g, '')} href={'#' + (this.state.name).replace(/\s/g, '')}> 
      {this.state.name} 
      </a> 
     </h2>>    
     </div> 
    <div id={(this.state.name).replace(/\s/g,'')} className="panel-collapse collapse"> 
     <div className="panel-body"> 
      {this.state.ingredients.map(ingredient => { 
      return <li className="list-group-item">{ingredient}</li> 
      })} 
      <div className="btn-group"> 
      <button className="btn btn-sm btn-info" data-toggle="modal" 
        data-target={'#' + (this.state.name).replace(/\s/g, '') + 'EditModal'}>Edit</button> 
      <button className="btn btn-sm btn-danger" data-toggle="modal" 
        data-target={'#' + (this.state.name).replace(/\s/g, '') + 'RemoveModal'} 
        >Delete</button> 
      </div> 
     </div> 
    </div> 
    </div> 
    </div> 


    <div className="modal modal-lg" id={(this.state.name).replace(/\s/g, '') + 'EditModal'} > 
     <div className="modal-content"> 
      <div className="modal-header"> 
      <h2>Edit {this.state.name}</h2> 
      </div> 
      <div className="modal-body"> 
      <ul className="list-group list-unstyle"> 
       {this.state.ingredients.map(ingredient => { 
       return <li className="list-group-item">{ingredient}</li> 
       })} 
      </ul> 
      </div> 
      <div className="modal-footer"> 
      <div className="btn-group"> 
       <button className="btn btn-sm btn-info" data-dismiss="modal">Save</button> 
       <button className="btn btn-sm btn-danger" data-dismiss="modal">Close</button> 
      </div> 
      </div> 
     </div> 
     </div> 


     <div className="modal modal-lg" id={this.state.name.replace(/\s/g, '') + 'RemoveModal'}> 
     <div className="modal-content"> 
      <div className="modal-body"> 
      <h3>This will remove the selected recipe. Are you sure?</h3> 
      </div> 
      <div className="modal-footer"> 
      <div className="btn-group"> 
       <button className="btn btn-sm btn-danger" data-dismiss="modal" onClick={this.onDeleteRecipe}>Delete</button> 
       <button className="btn btn-sm btn-info" data-dismiss="modal">Close</button> 
      </div> 
      </div> 
     </div> 
     </div> 
</div> 
); 
} 
} 

export default App; 

ответ

1

Я еще новичок, но ... Я построил рецепт коробке среагировать для FreeCodeCamp некоторые из них месяцев назад, поэтому я просто потянул его, чтобы сравнить мою функцию удаления с вашими.

Я замечаю, что вы относитесь к localStorage иначе, чем к моим. (Не то, чтобы мой способ был лучше или даже прав!) Интересно, почему-то проблема связана с этим дизайном. Ваша функция удаления переходит в localStorage и вносит изменения, затем вы запускаете setState для сортировки «повторно получить» recipeData, если я правильно читаю?

Наоборот, мое приложение объявляет переменную из localStorage, и я установил this.state.recipeArray, чтобы она была равна этой переменной. Затем все мои функции редактирования/добавления/удаления изменяются this.state.recipeArray, не localStorage. Сорта, как это:

handleDelete: function(e) { 
    e.preventDefault(); 

    var replacementRecipeArray = this.state.recipeArray.filter((recipe) => recipe.title !== e.target.name); 
    //dot-filter with ES6 fat-arrow returns all items where title doesn't match the one we clicked; IOW, it removes the one we want to delete 

    this.setState({ 
     recipeArray: replacementRecipeArray 
    }); 

    } 

Для того, чтобы получить какие-либо изменения в this.state.recipeArray обратно LocalStorage, я делаю localStorage.setItem каждый раз, когда я рендеринга страницы.

render() { 
    //first save current array to localstorage - wasn't reliable anywhere else 
    localStorage.setItem("_shoesandsocks_recipes", JSON.stringify(this.state.recipeArray)); 

    //render page 
    return (
     <div className="App"> 
     <div className="recipeContainer"> 
      // etc etc 

Для всех, кого я знаю, это сумасшедший дизайн, но он работает.

+0

Пробовал это по-своему, и, к сожалению, я получаю то же самое ... Спасибо за ответ, хотя! Попробовал ответить, но я еще не набрал 15 очков:/ –

+0

Состояние родительского компонента и localstorage меняются правильно, но по какой-то причине он удаляет неправильный компонент. Может быть, государство развращается, когда его передают ребенку, - но я не понимаю, как это сделать. –

+0

Вы получаете предупреждение о недостающих ключах, когда вы повторяете список рецептов? Я попытался вытащить ваш код на отдельную страницу приложения-примера, над которым я работаю, и я не получил его полностью (например, нет загрузочной загрузки), но подключен к локальному хранилищу localStorage, recipeData "после вашего приложения, и он отображает его на странице. Однако в консоли я получаю предупреждение о ключах. Может быть, не имея ключей, можно связать, какой объект будет удален? [see React docs on keys, здесь] (https://facebook.github.io/react/docs/lists-and-keys.html#keys) –

Смежные вопросы