2016-11-24 2 views
0

Код ниже работает только при удалении компонентаWillMount, который использует localStorage. При использовании LocalStorage он дает ошибкуПочему код перестает работать, когда я начинаю использовать localStorage?

this.state.interests.map не является функцией

Я попытался пошевелиться использование LocalStorage из компонентов, но это не поможет. Я полагаю, что использование локального хранилища каким-то образом изменяет this.state.interests, что они перестают быть массивом.

let interests = ["Музыка", "Компьютеры", "Радио"] 
 
let ListOfInterest = React.createClass({ 
 
    getInitialState: function() { 
 
    return {value: '', interests: interests}; 
 
    }, 
 
    componentWillMount() { 
 
    let local = localStorage.getItem('interests') 
 
    if (local) { 
 
     this.setState({interests: local}); 
 
    } else { 
 
     localStorage.setItem('interests', this.state.interests)} 
 
    }, 
 
    deleteInterest(key) { 
 
    delete interests[key] 
 
    this.setState(this.state) // without this line the page will not re-render 
 
    }, 
 
    addInterest() { 
 
    interests.unshift(this.state.value) 
 
    this.setState({value: ''}) 
 
    }, 
 
    handleChange(event) { 
 
    this.setState({value: event.target.value}) 
 
    }, 
 
    render() { 
 
    return <div className="interests"> 
 
     <b>Интересы</b> 
 
     <br/> 
 
     {this.state.interests.map((int, index) => { 
 
     return <button onClick={() => { 
 
      this.deleteInterest(index) 
 
     }} key={index} className="btn-interest">{int}</button> 
 
     })} 
 
     <input type='text' placeholder="Add" value={this.state.value} onChange={(e) => this.handleChange(e)}/> 
 
     <button onClick={() => { 
 
     this.addInterest() 
 
     }} className="add">Add interest</button> 
 

 
    </div> 
 
    } 
 
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

+1

Вам необходимо скомпоновать массив, прежде чем хранить его в локальном хранилище, и развернуть (разбор) его на обратном пути. –

+0

'this.setState (this.state)' выглядит ужасно! –

+0

Ты работаешь с автором http://stackoverflow.com/questions/40788157/warning-js45-warning-setstate-can-only-update-a-mounted-or-mounting-comp? – Barmar

ответ

1

У вас есть несколько вопросов, в вашем примере

  1. в localStorage.setItem второго аргумента должны быть String, вы не можете хранить Array (, когда вы это делаете, в хранилище будет разделяться цепочкой комой, потому что вызванный метод toString - [1, 2, 3].toString()), вам нужно stringify массива, прежде чем установить на хранение

    keyValue DOMString, содержащее значение, которое вы хотите присвоить ключ, который вы создаете/обновление.

    localStorage.setItem(
        'interests', JSON.stringify(this.state.interests) 
    ) 
    

    и parse когда прибудете значение

    let local = JSON.parse(localStorage.getItem('interests')); 
    
  2. this.setState(this.state) это не хороший способ для обновления состояния, необходимо обновить состояние, как так

    deleteInterest(key) { 
        this.setState({ 
        interests: this.state.interests.filter((el, i) => i !== key) 
        }) 
    }, 
    
    addInterest() { 
        this.setState({ 
        value: '', 
        interests: this.state.interests.concat(this.state.value) 
        }); 
    }, 
    

Example

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