【HarmonyOS NEXT】数据更新之后, 页面没有更新

【关键字】

数据更新 / List循环 / ForEach

【问题描述】

父组件有List循环data数组, 使用forEach渲染ListItem, ListItem中也使用forEach循环渲染Text组件。 页面刷新重新请求接口, data数据更新之后, 子组件的ListItem中Text的文案没有更新。

如示例中所示, mockData1和mockData2的区别是mockData2的第二项数据发生了变化, 但是并没有被重新渲染。

// demo.ets
interface IListItem {
text: string;
id: number;
}

interface IDataItem {
index: number;
list: IListItem[]
}

const mockData1 = [
{
index: 1,
list: [
{
text: '夏侯渊',
id: 101
},
{
text: '夏侯渊',
id: 102
},
]
},
{
index: 2,
list: [
{
text: '夏侯渊',
id: 201
},
{
text: '夏侯渊',
id: 202
},
]
},
];

const mockData2 = [
{
index: 1,
list: [
{
text: '夏侯渊',
id: 101
},
{
text: '夏侯渊',
id: 102
},
]
},
{
index: 2,
list: [
{
text: '曹操',
id: 2003
},
{
text: '诸葛',
id: 2004
},
]
},
];

@Observed class CategoryCardItem {
public id: number;
public text: string;

constructor(listItem: IListItem) {
this.id = listItem.id;
this.text = listItem.text;
}
}

@Observed class CategoryCardItemMap {
public index: number;
public list: CategoryCardItem[];

constructor(dataItem: IDataItem) {
this.index = dataItem.index;
this.list = dataItem.list;
}
}

@Component
struct PageForeachItem {
@ObjectLink dataItem: CategoryCardItemMap;
build() {
Column() {
ForEach(this.dataItem.list, (item: IListItem) => {
Column() {
Text(this.dataItem.index + '' + item.text + '' + item.id)
}
}, (item: IListItem) => item.id.toString())
}
.align(Alignment.TopStart)
.width('100%')
.backgroundColor('#c6c6c6')
}
}

@Entry
@Component
struct PageForeach {
@State data: CategoryCardItemMap[] = [];


aboutToAppear() {
setTimeout(() => {
mockData1.forEach((item: IDataItem) => {
this.data.push(new CategoryCardItemMap(item))
})
}, 500);
}

handleClick = () => {
console.log('click')
setTimeout(() => {
this.data = mockData2;
}, 500);
}

build() {
Column({ space: 8 }) {
Column() {
Text('top text')
}
.height('20%')
.width('100%')
.backgroundColor('#c6c6c6')

Row({ space: 8 }) {
// Flex() {
Column() {
Button('change', { type: ButtonType.Normal, stateEffect: true })
.borderRadius(8)
.backgroundColor(0x317aff)
.width(88)
.height(40)
.onClick(this.handleClick)
}
.flexBasis(88)
.flexShrink(0)
.height('100%')
.backgroundColor('#f5f5f5')

Column() {
List({ space: 8 }) {
ForEach(this.data, (item: IDataItem) => {
ListItem() {
PageForeachItem({ dataItem: new CategoryCardItemMap(item) })
}
}, item => item.index)
}
}
.height('100%')
.backgroundColor('red')
}
.width('100%')
.height('100%')
.backgroundColor('#fff')
}
}
}

【解决方案】

ForEach的渲染控制是依赖于键值是否变化来控制的,demo中,键值生成函数为item => item.index,使用index来作为键值,在数据更新时index键值未发生改变,因此不会触发ForEach的重新渲染,请使用item => JSON.stringify(item)或者默认缺省来实现数据的重新渲染。

ForEach的渲染控制参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-rendering-control-foreach-0000001820999585

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>