当前位置: 首页 > 知识库问答 >
问题:

循环内部的setState未正确更新状态

荀学文
2023-03-14

我有3个div。当我点击特定的按钮时,每个人都会有类活动。它们的每个div都有一个状态变量,每当它是真的时,我都会向连接到它的div添加class Name='active':

当我点击按钮时,状态改变,但是div没有激活类

async activeLang(e) {

  let lang = e.target.getAttribute('lang');

  for (const key in this.state.status) {

    if (key === lang) {
      await this.setState(state => {
        state.status[key] = true
      })
    }else{
      await this.setState(state => {
        state.status[key] = false
      })
    }
  
  }

  console.log(this.state.status);
}

当我将函数更改为此时,它会工作:

   activeLang(e) {
    let lang = e.target.getAttribute('lang');

    this.setState({
      status:{
       en: false,
       ar: false,
       fr: false,
      }
    })

    this.setState(state => {
      state.status[lang] = true
    })

    console.log(this.state.status);
  }

================================================

<ul>
 <li lang="en" onClick={this.activeLang} className={this.state.status.en ? 'active' : '' }>EN</li>
 <li lang="ar" onClick={this.activeLang} className={this.state.status.ar ? 'active' : ''}>AR</li>
 <li lang="fr" onClick={this.activeLang} className={this.state.status.fr ? 'active' : ''}>FR</li>
</ul>

================================================

<div className={this.state.status.en ? 'to-input en active' : 'to-input en'}>
 <input required type='text' onKeyUp={this.onInputChange} />
 <label title='Category name' placeholder='Ex. Business Cards'></label>
</div>

<div className={this.state.status.ar ? 'to-input ar active' : 'to-input ar'}>
 <input required type='text' onKeyUp={this.onInputChange} />
 <label title='اسم الفئة' placeholder='مثال: كروت العمل'></label>
</div>

<div className={this.state.status.fr ? 'to-input fr active' : 'to-input fr'}>
 <input required type='text' onKeyUp={this.onInputChange} />
 <label title='Nom de catégorie' placeholder='Ex. Cartes de visite'></label>
</div>

共有1个答案

杭志泽
2023-03-14

不要做循环。只要叫它一次:

const lang = e.target.getAttribute('lang');
this.setState(state => ({
   ...state,
   status: Object.keys(state.status).reduce((acc,key) => ({
     ...acc,
     [key]:state.status[key] === lang // set all statuses to false except for `lang`
   }),{});
});

编辑:

此外,setState不返回promise,您不能等待它。它确实接受回调,但这不是最好的解决方案(见上文)。

你不应该在循环中调用setState,会发生混乱的事情。

编辑#2:

从表面上看,我有一个更好的解决方案。一次只能有一个lang激活状态,因此您不需要status-您只需要知道激活的语言是什么,因此:

const state = { activatedLang: 'en' } // or 'fr' or 'ar'

然后你可以这样做:

this.setState({ activatedLang: e.target.getAttribute('lang') });
 类似资料:
  • 问题内容: 抱歉,我真的很想念React中子组件内部的传递。 我已经实现了一个包含3个组件的待办事项列表。 有一个组成部分和一个组成部分。状态仅存储在组件中。 显示器起步不错,因此可以看到道具。但是在提交表单后,我收到了以下错误: TypeError:this.props.tasks.map不是函数 当我console.log时,我没有得到我的数组,而是数组的长度。 你知道为什么吗? 编辑 :谢谢

  • 问题内容: 是否有原因在循环中调用会阻止其多次更新状态? 我有一个非常基本的jsbin,突出了我所看到的问题。有两个按钮。一个将状态计数器更新为1。另一个在循环中调用One的基础函数- 似乎将多次更新状态。 我知道此问题的几种解决方案,但我想确保首先了解这里的基本机制。为什么不能循环调用?我是否笨拙地编写了代码,以至于无法达到预期的效果? 问题答案: 从React Docs: setState()

  • 我有一个简单的组件 问题是我需要添加什么

  • 招呼: 我认为我没有正确更新我的复杂状态: 如何正确更新此状态?谢谢 https://codesandbox.io/s/intelligent-ellis-qi97k?file=/src/App.js

  • 我正在开发一个小待办事项应用程序,作为使用React的练习。我有一个这样的模拟服务: 在我的React应用程序中,我有一些包含TODO的状态: 是一个函数,我将它传递到我的组件中,当我想完成这样一个Todo时使用: 因此,每当用户单击复选框并使用调用时,就会从服务对象中删除它,并且状态应该更新,但最奇怪的事情发生了。 当调用时,todo将被正确删除,但当调用时,旧的todo仍然存在!如果我将内容写

  • 所以我有这个: 只是一个数组的数字例如然而没有给出正确的总数,但?我甚至放了一个超时延迟,看看这是否解决了问题。任何明显的还是我应该发布更多的代码?