【问题标题】:How to map over 2 arrays simultaneously and update the arrays according to condition in reactjs如何同时映射 2 个数组并根据 reactjs 中的条件更新数组
【发布时间】:2017-11-06 19:42:28
【问题描述】:

在 React 中,我将数据从父组件传递到子组件。两个组件都有自己的独立状态,其中包含一系列书籍。

我将父组件的书籍数组传递给子组件。我可以将子组件中的一本书添加到父组件。

在子组件中,我需要执行一个条件:如果子组件的书籍数组中有一个元素已经存在于父组件的书籍数组中,那么我需要更新书籍数组的一个属性子组件。

那么,我如何映射这两个数组并检查我的状况?

我正在尝试使用以下代码,但这不起作用。我知道下面的代码不是正确的方法,但我无法弄清楚如何继续

let parent_books = this.props.books;
  this.state.child_books.map((book,index) => {
      if(book === parent_books[index])
          book.shelf = parent_books[index].shelf

    }) 

因此,父书籍数组将有少量书籍已经存在于子书籍数组中。

所以我想检查父书籍数组中是否有一本书存在于子书籍数组中,然后我想将子书籍数组中的书架属性设置为父书籍数组中书籍的任何属性。

子组件中的所有书籍的初始书架属性为“无”。

任何人都可以建议如何进行此操作吗?

编辑

我正在尝试在下面的函数中实现代码。但是我在使用 setState 时遇到了一些问题。代码:

updateSearch = (searchString) => {
    let parent_books = this.props.books;
    this.setState({search: searchString.trim()})
    let searchResults = BooksAPI.search(this.state.search,1).then((book_search) => {
      if (book_search != undefined) {
        console.log(book_search)
          book_search.map((book) => book.shelf = 'none')
          this.setState({ books : book_search })
          console.log(this.state.books) //Gives the array of state
        }
    })

    console.log(this.state.books) //Gives an empty array
    this.state.books.map((book) => {
      const parent = parent_books.find(parent => parent === book );
      if(parent) {
        console.log(book.title);
        book.shelf = parent.shelf
      }
    })
  }

第二个console.log 没有返回处于其后未执行地图功能的状态的书籍数组。我做错了什么?

【问题讨论】:

  • 您是想简单地在render 中输出正确的shelf 值,还是要更新子图书状态?如果您想更新子图书状态,那么我假设代码将存在于子组件 componentWillReceiveProps()?在这种情况下,您可以setState 使用map 的结果。
  • @RickJolly 我想更新子书和父书的状态,这将使组件重新渲染。实际上,如果书存在,我想更改子组件中书的书架值在父组件中。父组件中的书在各自的书架中。在子组件中,最初所有书的书架属性设置为“无”
  • 你能解释一下为什么你的状态在两个组件中都很明显吗?将状态保存在一个地方不是更容易吗?
  • map() 返回一个数组。您需要使用forEach()setState 来更新组件的状态
  • @azium 实际上,我的父组件将进行 API 调用,其中默认情况下将有书籍在各自的书架上。所以,我对这一系列书籍有一个使用过的状态。在我的子组件,我可以搜索一本书并将这本书添加到父组件的书架。最初,在子组件中,书没有分配到任何书架。所以,我在搜索组件。搜索组件(子组件)将在搜索结果中列出所有书籍。从搜索页面,我可以将一本书添加到父组件的书架。

标签: javascript arrays reactjs


【解决方案1】:

不确定您的用例,但类似这样的方法可能有效:

componentWillReceiveProps(nextProps) {
    const {parent_books} = this.props;
    const {child_books} = this.state;
    if (parent_books !== nextProps.parent_books) {
      const books = child_books.map((child) => {
        const parent = parent_books.find(parent => parent.id === child.id);
        if (parent) {
          child.shelf = parent.shelf
        }
        return child;
      })
      this.setState({child_books: books});
    }
}

注意parent_books 应该是不可变的,这样parent_books !== nextProps.parent_books 才能工作。您可能不想使用 index 作为查找(我在示例中使用虚构的 id),因为父书和子书的顺序必须保持同步。

【讨论】:

  • 感谢您的回答。我会试一试,如果它有效,请告诉您。
  • 我试图实现你的答案。但是我遇到了一些问题。我在上面的问题的编辑中提到了这个问题。此外,我在代码中提到了这个问题作为注释。你能看一下吗?
  • setState 是异步的,因此您无法在 setState 之后访问 this.state.something 并期望它被更新。但是,setState 确实可以根据需要将可选回调作为第二个参数。
  • 您没有正确使用map。此外,您不能像 parent === book 那样进行相等性检查,因为这总是会返回 false,因为它们不是相同的对象引用。
  • 好的,谢谢。我会尝试做出相应的更改。
【解决方案2】:

由于要更新组件的状态,所以需要使用setState。此外,map 返回一个数组,因此请改用forEach;

componentDidMount(){
  this.state.child_books.forEach((book, i) => {
    if(book === parent_books[i]){
      this.setState({child_books: {shelf: [parent_books[i].shelf]}});
    }
  });
}

【讨论】:

  • 感谢您的解决方案。我会尝试一下,看看它是否有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多