22-ArkTs 常见错误
arkts-no-side-effects-imports
改用动态import
应用代码
import 'module'
建议改法
import('module')
arkts-no-func-props
应用代码
function foo(value: number): void { console.log(value.toString());}
foo.add = (left: number, right: number) => { return left + right;}
foo.sub = (left: number, right: number) => { return left - right;}
建议改法
class Foo { static foo(value: number): void { console.log(value.toString()); }
static add(left: number, right: number): number { return left + right; }
static sub(left: number, right: number): number { return left - right; }}
arkts-limited-esobj
应用代码
// lib.d.tsdeclare function foo(): any;
// main.etslet e0: ESObject = foo();
function f() { let e1 = foo(); let e2: ESObject = 1; let e3: ESObject = {}; let e4: ESObject = '';}
建议改法
// lib.d.tsdeclare function foo(): any;
// main.etsinterface I {}
function f() { let e0: ESObject = foo(); let e1: ESObject = foo(); let e2: number = 1; let e3: I = {}; let e4: string = '';}
拷贝
浅拷贝
TypeScript
function shallowCopy(obj: object): object { let newObj = {}; Object.assign(newObj, obj); return newObj;}
ArkTS
function shallowCopy(obj: object): object { let newObj: Record<string, Object> = {}; for (let key of Object.keys(obj)) { newObj[key] = obj[key]; } return newObj;}
深拷贝
TypeScript
function deepCopy(obj: object): object { let newObj = Array.isArray(obj) ? [] : {}; for (let key in obj) { if (typeof obj[key] === 'object') { newObj[key] = deepCopy(obj[key]); } else { newObj[key] = obj[key]; } } return newObj;}
ArkTS
function deepCopy(obj: object): object { let newObj: Record<string, Object> | Object[] = Array.isArray(obj) ? [] : {}; for (let key of Object.keys(obj)) { if (typeof obj[key] === 'object') { newObj[key] = deepCopy(obj[key]); } else { newObj[key] = obj[key]; } } return newObj;}
状态管理使用典型场景
Struct组件外使用状态变量
由于struct和class不同,不建议把this作为参数传递到struct外部使用,避免引起实例引用无法释放的情况,导致内存泄露。建议将状态变量对象传递到struct外面使用,通过修改对象的属性,来触发UI刷新。
不推荐用法
export class MyComponentController { item: MyComponent = null;
setItem(item: MyComponent) { this.item = item; }
changeText(value: string) { this.item.value = value; }}
@Componentexport default struct MyComponent { public controller: MyComponentController = null; @State value: string = 'Hello World';
build() { Column() { Text(this.value) .fontSize(50) } }
aboutToAppear() { if (this.controller) this.controller.setItem(this); // 不建议把this作为参数传递到struct外部使用 }}
@Entry@Componentstruct ObjThisOldPage { controller = new MyComponentController();
build() { Column() { MyComponent({ controller: this.controller }) Button('change value').onClick(() => { this.controller.changeText('Text'); }) } }}
推荐用法
class CC { value: string = '1';
constructor(value: string) { this.value = value; }}
export class MyComponentController { item: CC = new CC('1');
setItem(item: CC) { this.item = item; }
changeText(value: string) { this.item.value = value; }}
@Componentexport default struct MyComponent { public controller: MyComponentController | null = null; @State value: CC = new CC('Hello World');
build() { Column() { Text(`${this.value.value}`) .fontSize(50) } }
aboutToAppear() { if (this.controller) this.controller.setItem(this.value); }}
@Entry@Componentstruct StyleExample { controller: MyComponentController = new MyComponentController();
build() { Column() { MyComponent({ controller: this.controller }) Button('change value').onClick(() => { this.controller.changeText('Text'); }) } }}
Struct支持联合类型的方案
下面这段代码有arkts-no-any-unknown的报错,由于struct不支持泛型,建议使用联合类型,实现自定义组件类似泛型的功能。
不推荐用法
class Data { aa: number = 11;}
@Entry@Componentstruct DatauionOldPage { @State array: Data[] = [new Data(), new Data(), new Data()];
@Builder componentCloser(data: Data) { Text(data.aa + '').fontSize(50) }
build() { Row() { Column() { ForEachCom({ arrayList: this.array, closer: this.componentCloser }) } .width('100%') } .height('100%') }}
@Componentexport struct ForEachCom { arrayList: any[]; // struct不支持泛型,有arkts-no-any-unknown报错 @BuilderParam closer: (data: any) => void = this.componentCloser; // struct不支持泛型,有arkts-no-any-unknown报错
@Builder componentCloser() { }
build() { Column() { ForEach(this.arrayList, (item: any) => { // struct不支持泛型,有arkts-no-any-unknown报错 Row() { this.closer(item) }.width('100%').height(200).backgroundColor('#eee') }) } }}
推荐用法
class Data { aa: number = 11;}
class Model { aa: string = '11';}
type UnionData = Data | Model;
@Entry@Componentstruct DatauionPage { array: UnionData[] = [new Data(), new Data(), new Data()];
@Builder componentCloser(data: UnionData) { if (data instanceof Data) { Text(data.aa + '').fontSize(50) } }
build() { Row() { Column() { ForEachCom({ arrayList: this.array, closer: this.componentCloser }) } .width('100%') } .height('100%') }}
@Componentexport struct ForEachCom { arrayList: UnionData[] = [new Data(), new Data(), new Data()]; @BuilderParam closer: (data: UnionData) => void = this.componentCloser;
@Builder componentCloser() { }
build() { Column() { ForEach(this.arrayList, (item: UnionData) => { Row() { this.closer(item) }.width('100%').height(200).backgroundColor('#eee') }) } }}