reactjs map中的动态className在更新后不更改

oxosxuxt  于 2023-05-28  发布在  React
关注(0)|答案(2)|浏览(159)

sites变量中的active发生变化时,我试图更新我的react className,该变量被Map为循环遍历项目。
发生的情况是,如果活动状态更改为true,则className“非活动”不会消失,反之亦然。
代码:

// Context: this code is inside of the component
const [sites, setSites] = useState([]);  <--- Updated dynamically with fetch()
const changeActive = (id) => {
   const tmpSites = sites;
   for (const s in tmpSites) {
      if (tmpSites[s].id === id) {
         tmpSites[s].active = !Boolean(tmpSites[s].active);
      }
   }
   setSites(tmpSites);
};

return (
    {sites.length ? sites.map((item, i) => {
       return (
          <tr className={`${!Boolean(item.active) ? 'inactive' : ''}`} key={item.id}>
              // inbetween data
          </tr>
       )
    }) : null}
)
mo49yndu

mo49yndu1#

您需要创建sites数组的副本,对副本进行更改,然后将其设置为状态。永远不要直接改变状态,因为如果我们用相同的对象引用更新状态,它可能不会触发重新呈现。

const changeActive = (id) => {
   const tmpSites = [...sites];
   for (const s in tmpSites) {
      if (tmpSites[s].id === id) {
         tmpSites[s].active = !Boolean(tmpSites[s].active);
      }
   }
   setSites(tmpSites);
};
bttbmeg0

bttbmeg02#

因为您正在改变原始的sites Object,而不是在进行更改之前克隆它,所以useState“setSites”)实际上不会重新呈现组件,因为它无法比较前一个Object和当前Object,因为它们是相同的。
你必须对sites对象数组进行深度克隆:

const changeActive = (id) => {
   setSites(sites => {
     sites.map(site => ({  // ← first-level clone
        ...site            // ← second-level clone
        active: site.id === id ? !site.active : site.active
     }))
   })
}

必须使用setSites函数返回当前状态,然后才能可靠地深度克隆它。

相关问题