【问题标题】:Change a property of one object in an array of objects using setState (React)使用 setState (React) 更改对象数组中一个对象的属性
【发布时间】:2018-04-19 23:52:58
【问题描述】:

我的状态是代表书籍的对象数组。每本书都有许多属性,包括“shelf”属性和“id”。图书根据书架属性的设置显示:currentReading、wantToRead 或 read。

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

通过 setState 调用,我尝试 1) 使用传入的 id 属性隔离特定书籍,然后 2) 将该书的书架属性更改为用户选择的新书,然后 3) 重新用新书架渲染,这应该把书放在新书架上。我通过在数组上调用过滤器来隔离正确的书,但在那之后我迷路了。代码如下(首先是 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>

【问题讨论】:

    标签: javascript reactjs function filter


    【解决方案1】:

    您可以通过循环阅读书籍来做到这一点。当你找到带有 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 });
    }
    

    【讨论】:

    • 这行得通,我明白为什么你需要创建一个本地副本并更改它,然后将其换入。但我有一个问题 - 虽然我理解为什么 forEach 循环有效,但你为什么需要先做切片? – 休B
    • 切片用于制作状态数组的本地非可变副本。lorenstewart.me/2017/01/22/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-15
    • 1970-01-01
    • 2018-09-03
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多