JavaScript 中的对象分配

Object assigning in JavaScript

有一个对象 product,它的字段是对象 manufacturer。从我的服务器获取 manufacturers 后,我使用新数据重新分配产品字段 manufacturer(例如,获取的制造商有附加对象 avatar 作为其字段)。

async componentDidMount() {
  strapi.setToken(this.state.user.jwt);
  const products = await strapi.getEntries('products');
  products.forEach(async product => {
    const manufacturer = await strapi.getEntry('manufacturers', product.manufacturer.id); //fetched manufacturers has additional field "avatar"
    Object.assign(product.manufacturer, manufacturer);
  });

  console.log(products); // product.manufacturer.avatar is not null

  this.setState({
    products
  });

然后我尝试在 React render() 中显示头像。

render() {
    if (!this.state.products) return null;
    return(
        {this.state.products ? this.state.products.map(product => (
            // and it says that avatar is null 
            <img src={product.manufacturer.avatar.url} />

            // displays manufacturer with avatar object
            {console.log(product.manufacturer)}
            // says null! 
            {console.log(product.manufacturer.avatar)}
        ))}
    )
}

另外,当我使用 React Developer Tools 检查状态时,产品字段 manufacturer 有对象 avatar 并且它不为空。

更新: 感谢谢尔盖·苏斯洛夫

strapi.setToken(user.jwt);
      const fetchedProducts = await strapi.getEntries('products');
      const promices = fetchedProducts.map(async fetchedProduct => {
        const manufacturer = await strapi.getEntry('manufacturers', fetchedProduct.manufacturer.id);
        const product = { ...fetchedProduct, manufacturer };

        return product;
      });

      Promise.all(promices).then(products =>
        this.setState({
          products
        })
      );

这是因为第一次渲染时,您没有avatar值。这些值在第一次渲染后获取 (componentDidMount)。

您需要添加一个测试来考虑第一次渲染。

此外,您的 console.log 不一致的原因是因为您覆盖了产品的价值,为了更加不可变,您应该 .map 而不是 forEach,并且 return 您产品的副本,而不是修改现有产品。

我会怎么写:

constructor(props){
    super(props);

    this.state = {
        products: []
    }
}

render() {
    return this.state.products.map(product => {
        const {
            avatar = {}
        } = product.manufacturer;
        return (
            <img src={avatar.url} />
        );
    });
}

您正在使用不改变源对象的赋值方法进行赋值,结果是 returns 个新对象,选中此 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign。 你需要做这样的事情: 产品 = { ...产品, 制造商:您的分配声明 } 主要原因是foreach中的回调函数是异步的,js不会等待所有foreach函数调用完成,它一直在运行,考虑异步词,为此尝试使用Promise,或者最好尝试使用actions对于异步请求,感谢 librariy 或 sagas。