ã¯ããã«
çŸå Žã§Angularãè§Šãããããã£ããã¢ãããããªããã°ãªããªããªã£ãã®ã§ãããå ¬åŒããã¥ã¡ã³ãã®Signalã®ããŒãžå ã®äžæã®çè§£ã«ã€ãŸã¥ããŸããã
IMPORTANT: The readonly signals do not have any built-in mechanism that would prevent deep-mutation of their value.(éèŠ: èªã¿åãå°çšã·ã°ãã«ã«ã¯ãå€ã®æ·±éšå€ç°ã鲿¢ããçµã¿èŸŒã¿ã¡ã«ããºã ããããŸããã)
ãæ·±éšå€ç°ïŒã
ããããGeminiãšå£æã¡ããªãããããããããããããšãããšãªããšãããŸã§èŸ¿ãçãããšãã§ããŸããã
å®è£
æãã³ãŒãã¬ãã¥ãŒæã«éåžžã«éèŠãªãã€ã³ãã§ããããšãããã£ããããä»åã¯å
¬åŒã§èŠåãããŠãããDeep-mutationïŒæ·±ãéå±€ã®å€æŽïŒãã®èœãšã穎ã«ã€ããŠããSignal APIã®ä»çµã¿ããšãJavaScript (TypeScript) ã®æ§è³ªãã®äž¡é¢ããåããããã解説ããŸãã
1. ãããã Angular ã® Signal ãšã¯ïŒ
Signalã¯ãAngular v16ã§éçºè ãã¬ãã¥ãŒãšããŠå°å ¥ãããv17ã§å®å®çãšãªã£ãæ°ãããªã¢ã¯ãã£ããªç¶æ 管çã®ä»çµã¿ã§ããç°¡åã«èšããšãå€ã®å€åã远跡ã§ããè³¢ãç®±ãã®ãããªãã®ã§ãã
const count = signal(0); // 箱㫠0 ãå
¥ãã
console.log(count()); // ç®±ã®äžèº«ãèŠã -> 0
count.set(1); // ç®±ã®äžèº«ã 1 ã«å
¥ãæ¿ããïŒããã§UIçã«å€æŽãéç¥ãããïŒ
æå€§ã®ç¹åŸŽã¯ã.set() ã .update() ã§å€ãæŽæ°ãããã¿ã€ãã³ã°ã§ããã®Signalã«äŸåããŠãããã³ãã¬ãŒãïŒHTMLïŒã颿°ã ãããã³ãã€ã³ãã§åèšç®ïŒåæç»ïŒã§ããç¹ã«ãããŸããåŸæ¥ã®ä»çµã¿ïŒZone.jsãçšããå€åæ€ç¥ïŒããããã¯ããã«è»œéã§äºæž¬ããããåäœã«ãªããŸãã
2. Signal APIãä¿è·ããŠããç¯å²
SignalïŒç¹ã«èªã¿åãå°çšã®SignalïŒã¯ã.set() ã .update() ãšãã£ãã·ã°ãã«ãã®ãã®ã®å€ã眮ãæããã¡ãœãããé èœããŠãããŸãã
ããã«ãããæå³ããªãå ŽæããSignalèªäœã®å€ãæžãæããããããšãé²ãããšãã§ããŸãã
ããããã·ã°ãã«ãããªããžã§ã¯ããããé åããä¿æããŠããå Žåããã®ããããã£ãçŽæ¥æäœããããšã¯ JavaScript (TypeScript) ã®èšèªä»æ§äžå¯èœã§ãã
TypeScriptã«ããããªããžã§ã¯ããé åã«ã€ããŠã¯ã以äžãåç §ããŠãã ããã
3. Deep-mutationïŒæ·±ãéå±€ã®å€æŽïŒãšã¯äœã
ã§ã¯ãå®éã«ãã®ãçŽæ¥æäœã§ããŠããŸããåé¡ã¯ã©ã®ãããªåœ¢ã§çŸããã®ã§ããããïŒå ·äœçãªã³ãŒãäŸãèŠãŠã¿ãŸãããã
import { signal } from '@angular/core';
const user = signal({ name: 'Yamada', age: 30 });
const readonlyUser = user.asReadonly(); // èªã¿åãå°çšã®Signalå
// â ããã¯ã³ã³ãã€ã«ãšã©ãŒã«ãªãïŒSignal APIãä¿è·ããŠããïŒ
// readonlyUser.set({ name: 'Taro', age: 31 });
// â ïž ããããããã¯å®è¡ã§ããŠããŸãïŒããã deep-mutationïŒ
readonlyUser().name = 'Taro';
ãã®ãšããreadonlyUser().name = 'Taro' ãšããæäœã¯ãã·ã°ãã«ãšãããç®±ããå
¥ãæ¿ããŠããããã§ã¯ãªããç®±ã®äžã«ãããªããžã§ã¯ãã®ã¡ã¢ãªçªå°ã蟿ã£ãŠäžèº«ãæžãæããŠããç¶æ
ã§ãããã®ãããAngularã® Signal åïŒreadonlyïŒã®ãŸãŸã§ã¯ããã®æäœãããã©ã«ãã§ã¯ã³ã³ãã€ã«ã¬ãã«ã§é²ãããšãã§ããŸããã
4. ãªããããå±éºãªã®ãïŒ ã倿Žãæ€ç¥ãããªãææã
ãã®åé¡ã®æå€§ã®å±éºæ§ã¯ãAngularåŽã§å€æŽãæ€ç¥ã§ããªããªãããã§ãã
-
æ£åžžãªåäœ:
.set()ã.update()ã䜿ããšãã·ã°ãã«ã¯ãå€ãå€ãã£ãïŒããšåšå²ïŒäŸåé¢ä¿ïŒã«éç¥ããŸãã - Deep-mutationã®åé¡: ãªããžã§ã¯ãã®ããããã£ãçŽæ¥æžãæããŠããã·ã°ãã«åŽã¯ãä¿æããŠãããªããžã§ã¯ãïŒåç §å ïŒèªäœã¯å€ãã£ãŠããªãããšå€æããŸãããã®ããã倿Žéç¥ãçºçããŸããã
çµæãšããŠããããŒã¿ãæžãæããã¯ããªã®ã«ç»é¢ãæŽæ°ãããªãããcomputed ãåèšç®ãããªãããeffect ãçºç«ããªãããšãã£ãã远跡ãé£ãããã°ã®åå ã«ãªããŸãã
å ·äœçã«ãã³ã³ããŒãã³ãã®UIãæŽæ°ãããªããªã£ãŠããŸãå®éã®å€±æäŸãèŠãŠã¿ãŸãããã
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-user-profile',
template: `
<div>
<!-- ç»é¢ã«ã¯åžžã« "Yamada" ãšè¡šç€ºããããŸãŸã«ãªã -->
<p>åå: {{ user().name }}</p>
<button (click)="updateName()">ååã倿Ž</button>
</div>
`,
standalone: true
})
export class UserProfileComponent {
user = signal({ name: 'Yamada', age: 30 });
updateName() {
// â ïž Deep-mutation: ããããã£ãçŽæ¥æžãæãã
this.user().name = 'Taro';
// 倿°ã®å€èªäœã¯ 'Taro' ã«æžãæãã£ãŠããïŒã³ã³ãœãŒã«ã«ã¯ Taro ãåºãïŒ
console.log(this.user().name);
// ããããSignalèªäœã®åç
§ãå€ãã£ãŠããªãããAngularã¯å€åãæ€ç¥ã§ããã
// ç»é¢äžã® {{ user().name }} ã¯ãã£ããåæç»ãããªãïŒ
}
}
ãã®ããã«ããã³ã³ãœãŒã«ã®ãã°ã¯å€ãã£ãŠããã®ã«ãç»é¢ãåãæ¿ãããªãããšããéåžžã«åä»ãªç¶æ ãåŒãèµ·ãããŸãã
5. åé¿ã»å¯Ÿçããããã®ãã¹ããã©ã¯ãã£ã¹
ãã®åé¡ãé¿ããSignalã®ãªã¢ã¯ãã£ããªæ§è³ªãå®å šã«ä¿ã€ããã«ã¯ã以äžã®ææ³ãæšå¥šãããŸãã
â ã€ãã¥ãŒã¿ãã«ïŒäžå€ïŒãªæäœã培åºãã
ãªããžã§ã¯ããé
åã®å€ã倿Žããéã¯ãçŽæ¥ããããã£ãæžãæããã®ã§ã¯ãªããåžžã«ãæ°ãããªããžã§ã¯ãããäœæã㊠.set() ãŸã㯠.update() ã§æµã蟌ã¿ãŸãã
// â æªãäŸïŒDeep-mutationïŒ
// this.user().name = 'Taro';
// âïž è¯ãäŸïŒã€ãã¥ãŒã¿ãã«ãªæŽæ°ïŒ
this.user.update(u => ({ ...u, name: 'Taro' }));
é åã®å Žåãåæ§ã«ãæ¢åã®é åãçŽæ¥æäœããã®ã§ã¯ãªããæ°ããé åãäœæããŠçœ®ãæããŸãã
// â æªãäŸïŒDeep-mutationïŒ
// this.items().push({ id: 4, label: 'New' });
// âïž è¯ãäŸïŒã€ãã¥ãŒã¿ãã«ãªæŽæ°ïŒ
this.items.update(list => [...list, { id: 4, label: 'New' }]);
â¡ TypeScriptã® Readonly ãŠãŒãã£ãªãã£åãæå®ãã
ã·ã°ãã«ã®åå®çŸ©èªäœã« TypeScript ã® Readonly ïŒãŸã㯠ReadonlyArray ãªã©ïŒãæå®ããããããã£ãžã®ä»£å
¥ãã³ã³ãã€ã«ãšã©ãŒã«ããŠããŸãææ³ã§ãã
// åå®çŸ©ã§ãç®±ã®äžèº«ããžã®æžãæããé²ã
const user = signal<Readonly<{name: string, age: number}>>({
name: 'Yamada',
age: 30
});
// â ã³ã³ãã€ã«ãšã©ãŒã«ãªããããäºåã«ãã¹ã«æ°ã¥ãã
// user().name = 'Taro';
⢠ã€ã³ã¿ãŒãã§ãŒã¹ã®åããããã£ã readonly ã«ãã
ãããããå®çŸ©ããã€ã³ã¿ãŒãã§ãŒã¹ã®ããããã£ãã®ãã®ã« readonly 修食åãä»äžããäžæ³šæãªäžæžããé²ãææ³ã§ãã
// ã€ã³ã¿ãŒãã§ãŒã¹å®çŸ©ã§åããããã£ãèªã¿åãå°çšã«ãã
interface User {
readonly name: string;
readonly age: number;
}
const user = signal<User>({ name: 'Yamada', age: 30 });
// â ããããã£èªäœãèªã¿åãå°çšãªã®ã§ä»£å
¥ã§ããªã
// user().name = 'Taro';
ð¡ å®åã§ã®æšå¥šæ¹é
å®åã«ãããŠã¯ãããžã§ã¯ãã®èŠçŽã«ããããŸãããåºæ¬çã«ã¯**ãâ ã€ãã¥ãŒã¿ãã«ãªæŽæ°ãã培åºãã€ã€ãããã«å®å
šæ§ãæ
ä¿ãããã¢ãã«ã«å¯ŸããŠã¯ã⢠ã€ã³ã¿ãŒãã§ãŒã¹ã§ readonly ãä»äžããã**ãšããã¢ãããŒããçµã¿åãããã®ããæãå®å
šã§ããããã§ãã
6. ä»ã®ãã¬ãŒã ã¯ãŒã¯ã§ã®æ±ãã¯ïŒïŒJetpack Compose, ReactïŒ
å®ã¯ããã®ãDeep-mutationãæ€ç¥ãããªãããšããæåã¯ãAngularã®Signalç¹æã®æ¬ é¥ã§ã¯ãªãã**å€ãã®ææ°UIãã¬ãŒã ã¯ãŒã¯ã§å ±éããŠæ¡çšãããŠããèšèšææ³ïŒããã©ãŒãã³ã¹ãšäºæž¬å¯èœæ§ã®éèŠïŒ**ã«ãããã®ã§ãã
Jetpack Compose ã® MutableState
äŸãã°Androidéçºã§äœ¿ãããJetpack Composeã® MutableStateïŒmutableStateOfïŒã§ããåºæ¬çã«ã¯Angularã®Signalãšå
šãåãåé¡ãçºçããŸãã
MutableState ã«éåžžã®ãã¥ãŒã¿ãã«ãªãªããžã§ã¯ããå
¥ãããã®ããããã£ã ããçŽæ¥æžãæããŠãåã³ã³ããŒãºïŒåæç»ïŒã¯ããªã¬ãŒãããŸããã
// Composeã®äŸïŒAngularãšåããDeep-mutationã¯æ€ç¥ãããªãïŒ
val user = remember { mutableStateOf(User("Yamada", 30)) }
// â ãªããžã§ã¯ãå
ã®ããããã£ãçŽæ¥æžãæããŠãåæç»ãããªãïŒ
Button(onClick = { user.value.name = "Taro" }) { Text("Update") }
// âïž data classã® copy() ã䜿ã£ãŠå
šãæ°ããã€ã³ã¹ã¿ã³ã¹ãã»ããããå¿
èŠããã
Button(onClick = { user.value = user.value.copy(name = "Taro") }) { Text("Update") }
Composeã§ãããªããžã§ã¯ãã®å
éšããããã£ã«ãªã¢ã¯ãã£ãæ§ãæããããå Žåã¯ãããããã£èªäœãããããåå¥ã® MutableState ã«ããããããdata class ã䜿ã£ãŠåžžã«ã€ãã¥ãŒã¿ãã«ãªæŽæ°ïŒcopy()ïŒãè¡ããããšããã¹ããã©ã¯ãã£ã¹ãšãããŠããŸãã
React ã® useState
Reactã® useState ãåæ§ã«ããªããžã§ã¯ãã®ããããã£ãçŽæ¥æžãæããŠãïŒstate.name = 'Taro'ïŒããªããžã§ã¯ãèªäœã®åç
§ïŒã¡ã¢ãªçªå°ïŒãå€ãããªãããåã¬ã³ããªã³ã°ãããŸãããã¹ãã¬ããæ§æãªã©ã«ãããæ°ãããªããžã§ã¯ããžã®çœ®ãæããå¿
é ã§ãã
// Reactã®äŸ
const [user, setUser] = useState({ name: "Yamada", age: 30 });
// â åç
§ãå€ãããªãããåã¬ã³ããªã³ã°ãããªã
user.name = "Taro";
setUser(user);
// âïž æ°ãããªããžã§ã¯ããã»ãããã
setUser({ ...user, name: "Taro" });
7. ãã€ã³ã¿ã»ã¡ã¢ãªã¢ãã¬ã¹ããçè§£ããDeep-mutationïŒè§£èª¬ïŒ
ããããã¯ã瀟å ã®ã·ãã¢ãšã³ãžãã¢ã®æ¹ã«ã¬ãã¥ãŒããã ãã
ããã€ã³ã¿ããšãã芳ç¹ã§çè§£ãããšããæ·±ãçè§£ã§ããã®ã§ã¯ïŒ
ãšææããã ããå 容ãããšã«ãèªåãããã«äžéšã ãã®çè§£ãããŠãããã«æ°ã¥ãããããçªå€ç·šãšããŠç޹ä»ãããŠããã ããŸãã
7-1. ãã¡ã¢ãªã¢ãã¬ã¹ããšã¯ïŒ
åºæ¬æ
å ±æè¡è
ãªã©ã§åŠç¿ãããŠãããšãããã³ã³ãã¥ãŒã¿ã®ã¡ã¢ãªïŒRAMïŒã¯ãèšå€§ãªéã®ããŒã¿ãæ ŒçŽããããã®ç®±ãããã£ãšäžŠãã æ¬æ£ã®ãããªãã®ã§ããããšããçè§£ããã ããŠããéãã§ãã
ãã®äžã§ãã¡ã¢ãªã¢ãã¬ã¹ãšã¯ããã®æ¬æ£ã®ããããã®æ£ã«æ¯ããããäœæçªå·ãã«ããããŸããããã°ã©ã ãæ±ããã¹ãŠã®ããŒã¿ã¯ããã®äœæã®ã©ããã«ä¿ç®¡ãããŠããŸãã
ã¡ã¢ãªïŒæ¬æ£ã®ã€ã¡ãŒãžïŒ
ââââââââââââ¬âââââââââââ¬âââââââââââ¬âââââââââââ¬âââ
â çªå° 0x01 â çªå° 0x02 â çªå° 0x03 â çªå° 0x04 â ...
â ããŒã¿A â ããŒã¿B â ããŒã¿C â ããŒã¿D â
ââââââââââââŽâââââââââââŽâââââââââââŽâââââââââââŽâââ
7-2. ããã€ã³ã¿ããšã¯ïŒ
C/C++ãGoã§ã¯ããã€ã³ã¿ãšããæŠå¿µãæç€ºçã«ç»å ŽããŸãã
ãã€ã³ã¿ãšã¯ãããŒã¿ãã®ãã®ãã§ã¯ãªããããŒã¿ãä¿ç®¡ãããŠããäœæïŒã¡ã¢ãªã¢ãã¬ã¹ïŒãèšé²ããã¡ã¢ã®ãããªãã®ã§ãã
ãã€ã³ã¿å€æ° user ã¡ã¢ãªäžã®å®ããŒã¿
âââââââââââââââââââ âââââââââââââââââââââââââââ
â äœæ: 0x03 ãæã â âââ â çªå° 0x03: â
â â â { name:"Yamada", age:30 }â
âââââââââââââââââââ âââââââââââââââââââââââââââ
JavaScript/TypeScriptã§ã¯ããã€ã³ã¿ããšããçšèªã¯äœ¿ããŸãããããªããžã§ã¯ããé åã倿°ã«ä»£å ¥ãããšãã倿°ãå éšçã«ä¿æããŠããã®ã¯ããŒã¿ãã®ãã®ã§ã¯ãªããã¡ã¢ãªäžã®äœæïŒåç §ïŒãã§ããä»çµã¿ãšããŠã¯ãã€ã³ã¿ãšåãããšãè£åŽã§è¡ãããŠããŸãã
7-3. (äžèšãèžãŸããŠ)Deep-mutationã§äœãèµ·ããŠããã®ãïŒ
ãã®ä»çµã¿ãèžãŸãããšãuser().name = 'Taro' ãšããæäœãäœãããŠããã®ããå³ã§èŠããšäžç®çç¶ã§ãã
â Deep-mutationïŒããããã£ãçŽæ¥æžãæãïŒããå ŽåïŒ
ãæäœåã
Signal(user) ã¡ã¢ãª
âââââââââââââââââââ ââââââââââââââââââââââââââââ
â äœæ: 0x03 ãæã â âââ â çªå° 0x03: â
â â â { name:"Yamada", age:30 } â
âââââââââââââââââââ ââââââââââââââââââââââââââââ
user().name = 'Taro' ãå®è¡ãããš...
ãæäœåŸã
Signal(user) ã¡ã¢ãª
âââââââââââââââââââ ââââââââââââââââââââââââââââ
â äœæ: 0x03 ãæã â âââ â çªå° 0x03: â
â ïŒå€ãã£ãŠãªãïŒïŒâ â { name:"Taro", age:30 } â â äžèº«ã ãå€ãã£ã
âââââââââââââââââââ ââââââââââââââââââââââââââââ
â ðŽ SignalãèŠãŠããã®ã¯ãäœæãã ããäœæ 0x03 ã®ãŸãŸãªã®ã§ãå€åãªãããšå€å®
âïž .update() ã§æ°ãããªããžã§ã¯ãã«çœ®ãæããå ŽåïŒ
ãæäœåã
Signal(user) ã¡ã¢ãª
âââââââââââââââââââ ââââââââââââââââââââââââââââ
â äœæ: 0x03 ãæã â âââ â çªå° 0x03: â
â â â { name:"Yamada", age:30 } â
âââââââââââââââââââ ââââââââââââââââââââââââââââ
user.update(u => ({ ...u, name: 'Taro' })) ãå®è¡ãããš...
ãæäœåŸã
Signal(user) ã¡ã¢ãª
âââââââââââââââââââ ââââââââââââââââââââââââââââ
â äœæ: 0x07 ãæã â âââ â çªå° 0x07: â
â ïŒæ°ããäœæïŒïŒ â â { name:"Taro", age:30 } â â æ°ããå Žæã«æ°ããããŒã¿
âââââââââââââââââââ ââââââââââââââââââââââââââââ
ââââââââââââââââââââââââââââ
â çªå° 0x03:ïŒå€ãããŒã¿ïŒ â
â { name:"Yamada", age:30 } â â ããåç
§ãããªã
ââââââââââââââââââââââââââââ
â äœæã 0x03 â 0x07 ã«å€ãã£ãïŒSignalã¯ãå€åããïŒããšæ€ç¥ â åæç»ãããïŒ
C/C++ã»Goã§ã®è¡šçŸ
â» ãããŸã§ããã€ã³ã¿ã®æåãšããŠã®é¡äŒŒæ§ãã説æããããã®å³è§£ã§ãããåãã¬ãŒã ã¯ãŒã¯å ã«ãããŠå šãåãåŠçããããŠããããã§ã¯ãããŸããããæŠå¿µãšããŠã¯ä»¥äžã®ããã«è¡šçŸã§ããŸãã
// Cèšèªã§ã®äŸã
User *user = &original_user; // ãã€ã³ã¿ãäœæ 0x03 ãæããŠãã
// â Deep-mutationïŒäœæã¯ãã®ãŸãŸãäžèº«ã ãæžãæãïŒ
user->name = "Taro"; // ãã€ã³ã¿ã®æãå
㯠0x03 ã®ãŸãŸ â å€åãæ€ç¥ã§ããªã
// âïž æ°ãããªããžã§ã¯ããžã®çœ®ãæãïŒäœæèªäœãå€ããïŒ
User new_user = { .name = "Taro", .age = 30 };
user = &new_user; // ãã€ã³ã¿ãæ°ããäœæ 0x07 ãæã â å€åãæ€ç¥ã§ãã
// Goèšèªã§ã®äŸã
user := &User{Name: "Yamada", Age: 30} // ãã€ã³ã¿ãäœæ 0x03 ãæããŠãã
// â Deep-mutationïŒäœæã¯ãã®ãŸãŸãäžèº«ã ãæžãæãïŒ
user.Name = "Taro" // ãã€ã³ã¿ã¯ 0x03 ã®ãŸãŸ â å€åãæ€ç¥ã§ããªã
// âïž æ°ãããªããžã§ã¯ããžã®çœ®ãæãïŒäœæèªäœãå€ããïŒ
user = &User{Name: "Taro", Age: 30} // ãã€ã³ã¿ãæ°ããäœæ 0x07 ãæã â å€åãæ€ç¥ã§ããïŒ
ãŸãšãããš
ãã¬ãŒã ã¯ãŒã¯ãç£èŠããŠããã®ã¯ã倿°ãæã瀺ãäœæïŒã¡ã¢ãªã¢ãã¬ã¹ïŒãå€ãã£ããã©ãããã ãã§ãäœæã®å ã«ãããéšå±ã®äžèº«ãããããå€ãã£ãŠããäœæèªäœãåããªããäœãå€ãã£ãŠããªãããšå€æãããããšãçç±ã®ããã§ããã
8. ãŸãšã
ãããã§ããã§ããããã
æ¹ããŠãä»åã®èŠç¹ããŸãšãããšä»¥äžã®éãã§ãã
- Signal APIã®ä¿è·ç¯å²: ã·ã°ãã«ã®å€ãã®ãã®ã®ã眮ãæãïŒã»ããïŒãã®ã¿ä¿è·ã§ããã
- Signalã§é²ããªãããšïŒDeep-mutationïŒ: ä¿æããŠãããªããžã§ã¯ãå éšã®ããããã£ã®çŽæ¥çãªæžãæãã
- ä»ãã¬ãŒã ã¯ãŒã¯ãšã®å ±éç¹: ComposeãReactãªã©ãå€ãã®ææ°UIæè¡ãšå ±éã®ãåç §å€åãç£èŠãããææ³ã«åºã¥ããŠããã
- ãªã¹ã¯: çŽæ¥æžãæãããšAngularã倿Žãæ€ç¥ã§ãããUIã®äžæŽåããã°ã®æž©åºã«ãªãã
è€éãªãªããžã§ã¯ããSignalã§ç®¡çããå Žåã¯ãã€ãã¥ãŒã¿ãã«ãªããŒã¿æäœãšãé©åãªåå®çŸ©ïŒReadonlyçïŒããçµã¿åãããããšã§ãå ç¢ãªããã³ããšã³ãéçºãå¯èœã«ãªãããšããåããããã ããããšæããŸãã
ä»åŸãAngularã®ãã£ããã¢ãããåæ»ã«ã§ãããããªåå¿è åãã³ã³ãã³ããèšäºåããŠãããŸãã®ã§ã楜ãã¿ã«ããŠããŠãã ããïŒ
åè
- Angular - Signals
- React - useState
- Android Developers - API Reference - Jetpack Compose - MutableState
- C++ Pointers