- リンクを取得
- ×
- メール
- 他のアプリ
- リンクを取得
- ×
- メール
- 他のアプリ
問題の分析
LWC(Lightning Web Component)でApexから取得したデータを操作しようとすると、「Uncaught TypeError: 'set' on proxy: trap returned falsish for property
」というエラーが発生しました。このエラーの原因は、@wire
デコレータを使用して取得したデータが読み取り専用(read-only)であり、直接変更することができないためです。
解決策
この問題を解決するには、データを直接操作するのではなく、クローンを作成してそれを変更する必要があります。以下に修正済みのコードを示します。
修正済みコード
HTML:
<template> <template if:true={wiredContact}> {wiredContact.Name} <lightning-input value={wiredContact.Name} onchange={updateName}></lightning-input> </template> </template>
JavaScript:
import { LightningElement, wire, track } from 'lwc'; import myContact from '@salesforce/apex/ContactController.fetchContact'; export default class Myrefreshapextest extends LightningElement { @track wiredContact; @wire(myContact) fetchedContact({ error, data }) { if (data) { console.log(JSON.stringify(data)); // データをクローンして操作可能にする this.wiredContact = { ...data }; } else if (error) { console.error(error); } } updateName(event) { const newName = event.detail.value; console.log('New Name:', newName); console.log('Current wiredContact:', JSON.stringify(this.wiredContact)); // 名前フィールドを更新した新しいオブジェクトを作成 this.wiredContact = { ...this.wiredContact, Name: newName }; } }
Apex:
public class ContactController { @AuraEnabled(cacheable=true) public static Contact fetchContact() { return [SELECT Id, Name FROM Contact LIMIT 1]; } }
修正ポイントの解説
スプレッド構文
{ ...data }
を使用したクローン作成:@wire
デコレータで取得したデータは読み取り専用のため、そのまま操作するとエラーになります。スプレッド構文を使用して新しいオブジェクトを作成することで、この問題を回避しました。updateName
で新しいオブジェクトを作成:wiredContact
を直接変更せず、更新したデータを反映した新しいオブジェクトを作成しました。@track
の使用:@track
を使用してwiredContact
プロパティの変更を検知し、コンポーネントを再描画可能にしました。
補足情報
深いネスト構造のクローン:
オブジェクトが深くネストされている場合は、JSON.parse(JSON.stringify(data))
またはstructuredClone(data)
を使用すると安全にクローンできます。ただし、後者はブラウザのサポート状況に注意が必要です。@track
の必要性:
最新のLWCでは、オブジェクト全体を再割り当てする場合、明示的な@track
は不要ですが、複雑な状況では利用する価値があります。
この修正を適用することで、「set on proxy
」エラーを回避し、wiredContact
オブジェクトのフィールドを安全に更新できるようになります。
コメント
コメントを投稿