简体   繁体   English

当状态更新 React JS 时,Map 函数不会呈现新元素

[英]Map function won't render new element when state is updated React JS

I have 2 components, OneBook component has an option to "add to collection", i have an onClick event that sets the state of "collect" to true (default value is false of course).我有 2 个组件,OneBook 组件有一个“添加到集合”的选项,我有一个 onClick 事件将“收集”的状态设置为 true(当然默认值为 false)。 In my second component "Collection", i have a map function that returns a list of book elements (with title, author,etc) IF its collect state is true.在我的第二个组件“Collection”中,我有一个 map 函数,如果它的收集状态为真,它会返回一个书籍元素列表(包括标题、作者等)。 Yet when i click on the "add to collection" which sets the state to true successfully (because i console logged it and the state is being updated), the map function isn't showing the elements even though they have the state of collect set as true.然而,当我单击“添加到集合”将状态成功设置为 true 时(因为我控制台记录了它并且状态正在更新),即使它们具有集合状态,地图功能也没有显示元素一样真实。

Here is my code for clarity.为了清楚起见,这是我的代码。 Or you can see the code sandbox to edit the code directly: https://codesandbox.io/s/stupefied-lewin-06f6m?file=/src/OneBook.js或者你可以看到代码沙箱直接编辑代码: https : //codesandbox.io/s/stupefied-lewin-06f6m?file=/src/OneBook.js

OneBook.js一本书.js

const [collect, setCollect] = useState(true)

return (
<small onClick={() => {setCollect(true);console.log(collect)}} className="addcollect"><i className="fas fa-bookmark bookmark"></i>Add To Collection</small>
)

Collection.js集合.js

{
   books.map(book => {
      return (book.collect? <li><img src={book.img} alt="img"/>{book.title} <span>{book.author}</span></li> : "")
    })
}

You were not updating the books value in context properly and also collect value has no impact on the orignal books array in context.您没有正确更新上下文中的书籍值,并且收集值对上下文中的原始书籍数组没有影响。 Have a look at the codesandbox below.看看下面的代码和框。

Let me know if it helps让我知道它是否有帮助

Codesandbox link 代码沙盒链接

Note:笔记:

As you asked for the explanation of this:当您要求对此进行解释时:

return { ...elem, collect: true };

I am using the spread operator here, which essentially keep all the value of books object and just update the collect field.我在这里使用了 spread 运算符,它基本上保留了 books 对象的所有值,只是更新了 collect 字段。

Let's see one example below:让我们看下面的一个例子:

A = {
 a: 1,
 b: 2
}

B = {...A, b: 3}

Now B will be having something like this structure:现在 B 将有这样的结构:

{
 a: 1,
 b: 3
}

As i see you dont update the actual book object in the context when you click on add to collection.正如我所看到的,当您单击“添加到收藏”时,您不会更新上下文中的实际图书对象。

change your onClick fn to this将您的 onClick fn 更改为此

const setCollect = (value) => {
  //loop though all the books and change the collect property of the book after the add to collection click
  const showedBook = books.map(b => {
    if (b.isbn !== props.isbn) {
      return b;
    }

    return {
      ...b,
      collect: value,
    };
  });

  setBooks(
    [...showedBook]
  );
};


);

}; };

<small onClick={() => setCollect(true)}....

updated demo更新演示

It is because the collect state has no relations to book object.这是因为collect状态与 book 对象没有关系。 So you need to create a function that updates the books .所以你需要创建一个更新books的函数。

const addToCollection = () => {
    books.map((book) => {
      if (book.isbn === props.isbn) {
        console.log(book.isbn)
        book.collect = true;
      }
    });

    return;
  };

Then call it on click event on your Add to collection button.然后在添加到收藏按钮上的单击事件上调用它。

<small
   onClick={() => {
   addToCollection();
   }}
   className="addcollect"
 >
   <i className="fas fa-bookmark bookmark"></i>Add To Collection
</small>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM