LWCで「Uncaught TypeError: 'set' on proxy: trap returned falsish for property 'Name'」エラーを解決する方法

問題の分析

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];
    }
}

修正ポイントの解説

  1. スプレッド構文 { ...data } を使用したクローン作成:
    @wireデコレータで取得したデータは読み取り専用のため、そのまま操作するとエラーになります。スプレッド構文を使用して新しいオブジェクトを作成することで、この問題を回避しました。

  2. updateNameで新しいオブジェクトを作成:
    wiredContactを直接変更せず、更新したデータを反映した新しいオブジェクトを作成しました。

  3. @trackの使用:
    @trackを使用してwiredContactプロパティの変更を検知し、コンポーネントを再描画可能にしました。


補足情報

  • 深いネスト構造のクローン:
    オブジェクトが深くネストされている場合は、JSON.parse(JSON.stringify(data))またはstructuredClone(data)を使用すると安全にクローンできます。ただし、後者はブラウザのサポート状況に注意が必要です。

  • @trackの必要性:
    最新のLWCでは、オブジェクト全体を再割り当てする場合、明示的な@trackは不要ですが、複雑な状況では利用する価値があります。


この修正を適用することで、「set on proxy」エラーを回避し、wiredContactオブジェクトのフィールドを安全に更新できるようになります。

コメント