使用setState更改对象数组中一个对象的属性(React)

时间:2018-04-19 15:47:11

标签: javascript reactjs function filter

我的状态是代表书籍的一系列对象。每本书都有许多属性,包括“架子”属性和“id”。书籍根据货架属性的设置显示:CurrentlyReading,wantToRead或read。

每本书都有一个下拉选项,允许用户更改书架设置。我有一个事件处理程序设置,它传递新的架子和书籍ID。

使用setState调用,我试图1)使用传入的id属性隔离特定的书,然后2)将该书的shelf属性更改为用户选择的新书,然后3)重新使用新架子进行渲染,这应该将书放在新架子上。我通过调用数组上的filter来隔离正确的书,但之后我迷路了。代码如下(首先是JS,然后是带有下拉列表的JSX)。我怎样才能做到这一点,我尝试了几种方法,包括传入prevState。下面的最新一个是我试图从reactTraining模拟的一个例子,但是它给了我一个语法错误:setState调用中出现意外的令牌。

constructor() {
    super();
    this.state = {
        books: []
    }
};

componentDidMount() {
    getAll().then((books) => {
        this.setState({ books })
    })
}

onSelectChange = (e) => {
    const id = e.target.name
    const newShelf = e.target.value
    console.log(id, newShelf)
    let changeShelf = this.state.books.filter((book) => { return 
        book.id === id})

    this.setState({
        changeShelf[0].shelf: changeShelf[0].newShelf
    })
}

<li key={book.id}>
    <div className="book">
        <div className="book-top">
            <div className="book-cover" style={{ width: 128, height: 
                193, backgroundImage: `url("${ 
                book.imageLinks.thumbnail 
                }")` }}>
            </div>
            <div className="book-shelf-changer">
                <select name={book.id} onChange={onSelect}>
                    <option value="none" disabled>Move to...</option>
                    <option value="currentlyReading">Currently 
                        Reading</option>
                    <option value="wantToRead">Want to Read</option>
                    <option value="read">Read</option>
                    <option value="none">None</option>
                 </select>
            </div>
        </div>
        <div className="book-title">{book.title}</div>
        <div className="book-authors">{book.authors}</div>
    </div>
</li>

1 个答案:

答案 0 :(得分:0)

你可以通过书籍循环来完成。当您找到带有id的书时,只需更改货架属性:

onSelectChange = (e) => {
    const id = e.target.name
    const newShelf = e.target.value
    console.log(id, newShelf)
    const books = this.state.books.slice(); // Create local copy to change.
    books.forEach((book) => {
      if (book.id === id) {
        book.shelf = newShelf;
      }
    });
    this.setState({ books });
}