javascript - for 循环内的 setState 无法正确更新状态
问题描述
我有 3 个 div。当我单击特定按钮时,每个人都会激活课程。他们的每个 div 都有一个状态变量,只要它是真的我添加 className='active' 到连接到它的 div :
当我单击按钮时,状态会发生变化,但 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>
解决方案
不要循环执行。只需调用一次:
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
不返回承诺,你不能await
。它确实接受回调,但这不是最好的解决方案(见上文)。
你永远不应该setState
循环调用,会发生混乱的事情。
编辑#2:
从外观上看,我为您的状态提供了更好的解决方案。一次只能有一个语言处于活动状态,因此您不需要status
- 您只需要知道激活的语言是什么,因此:
const state = { activatedLang: 'en' } // or 'fr' or 'ar'
然后你可以这样做:
this.setState({ activatedLang: e.target.getAttribute('lang') });
推荐阅读
- angular - 实现账户单一手机登录
- r - Parallel R:从具有并行的子源脚本输出控制台消息
- c++ - 调试和编译类依赖于 VS Code 的文件
- typescript - 有没有办法在 TypeScript 中创建标记的数组联合?
- angular - https上的角标头
- sms - 是否有任何 ADB 命令来获取“默认消息传递应用程序”的包名称?
- reactjs - 为什么不使用 react 和 typescript 专门检查未定义的值时条件评估为 false?
- mysql - laravel 使用模型和控制器连接两个表并显示所有数据
- docker - 如何使用 make 文件将环境变量传递给 Docker 组合
- react-native - 使用crypto-js解密base64文件会导致高内存堆