如何在循环中设置状态

How to set state in loop

我正在尝试从 .cvs 文件导入 Wordpress 类别。我正在用 React 写一个简单的应用程序,我有一个函数:

componentDidUpdate( prevProps, prevState ) {
    let that = this
    
    if (prevState.syncStatus !== this.state.syncStatus && this.state.syncStatus == 'posts') {    
        row_terms.forEach( (element, inx) => {
            let parent = that.state.parent_id;
            let _terms = element.split('>')
            _terms = _terms.map(function(e){return e.trim();});
            const total  = _terms.length
        
            _terms.forEach( (_term, index) => {
                addCategory(_term, that.state.parent_id).then(result => {
                    let term_id
        
                    if( result.code && result.code == 'term_exists' ) {
                        term_id = result.data.resource_id
                    } else {
                        term_id = result.id
                    }
        
                    if ( ( 1 + index ) === total ) {
                        categories.push(term_id)
                    } else {
                        that.setState({parent_id: term_id})
                    }
                })
                
            })
        })
    }
}

并添加类别:

import WooCommerce from './woocommerce'

async function addCategory(name, parent) {
    console.log('parent', parent)
    try {
        return await WooCommerce.postAsync('products/categories', {name: name, parent: parent}).then(result => {
            return JSON.parse(result.toJSON().body);
        });
    } catch (e) {
        return e
    }

}
export default addCategory

并设置初始值

constructor(props) {
    super()
    this.state = {
        parent_id: 0,
    }
}

我想一个接一个地添加类别,因为我需要为子类别设置parent_id。所以当它添加一个类别和条件

if ( ( 1 + index ) === total ) {

不满足 我想设置 parent_id 然后在下一次迭代中使用它。但是没用。

当我使用

console.log(that.state.parent_id)

之后

that.setState({parent_id: term_id})

它打印出正确的值。

当我 运行 我的应用程序在发出任何请求之前,它会为所有类别打印 0(console.log in addCategory() )。

.forEach() 不知道 addCategory 的异步性;你要么必须链接所有这些 thens,要么最好只使用 async/await 和普通的旧 for 循环,它可以与 await 一起使用而无需额外要跳过的圈。

假设您想遍历所有 row_terms 并处理它们,您还需要 await 这些承诺...

const categories = [];
const promises = row_terms.map(async (element) => {
  const terms = element.split(">").map((e) => e.trim());
  const total = terms.length;
  let parent = null;
  for (let i = 0; i < total; i++) {
    const term = terms[i];
    const result = await addCategory(term, parent);
    const term_id = result.code && result.code === "term_exists" ? result.data.resource_id : result.id;
    if (i === total - 1) {
      categories.push(term_id);
    } else {
      parent = term_id;
    }
  }
});
await Promise.all(promises);