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。
有一个对象 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。