结合MUI-Datatables实现AWS订阅遇更新异常,求技术帮助
Hey there, let's work through this issue together. The core problem here is that you're not updating your component state correctly (which prevents re-renders) and not leveraging Amplify's cache/subscription handling properly to sync with MUI-Datatables. Here's how to fix it step by step:
1. Stop Directly Modifying this.state (Critical!)
React relies on setState() to trigger component re-renders. Any direct assignment like this.state.Records3 = ... won't tell React to update the UI. This is why your table only refreshes when you type in the input—because that action triggers a setState via handleChange.
Fix in ListRecords.js
Replace your direct state assignments with proper state handling, and let the Connect component feed data directly to the table instead of storing it in local state:
render() { const columns = [ { name: "Datum & Uhrzeit", label: "Datum & Uhrzeit" }, { name: "Eintrag", label: "Eintrag" }, { name: "Arzt", label: "Arzt" }, { name: "Patient", label: "Patient" }, ]; const options = { /* keep your existing options */ }; return ( <div> <Connect query={graphqlOperation(listRecordss)} subscription={graphqlOperation(onCreateRecords)} onSubscriptionMsg={(prevQueryData, newSubscriptionData) => { // Update cached query data with the new record return { ...prevQueryData, listRecordss: { ...prevQueryData.listRecordss, items: [newSubscriptionData.onCreateRecords, ...prevQueryData.listRecordss.items] } }; }} > {({data, loading, error}) => { if (loading) return <div>Loading...</div>; if (error) return <div>Error: {error.message}</div>; // Generate table data directly from Connect-provided data const tableData = data.listRecordss.items.map(rest => [ rest.createdAt, rest.record, rest.arzt, rest.patient ]); return ( <MUIDataTable title={"Leistungen"} data={tableData} columns={columns} options={options} /> ); }} </Connect> </div> ); }
2. Update Mutation Cache to Trigger Immediate Table Refresh
Right now, your mutation doesn't update the existing query cache, so the table doesn't know a new record was added until the subscription fires or you trigger a re-render manually. Add an update function to your mutation to refresh the cache instantly:
Fix in AddRecord.js
addRecord = async () => { try { await this.props.client.mutate({ mutation: gql(createRecords), variables: { input: { record: this.state.Record } }, update: (cache, { data: { createRecords } }) => { // Read current records from cache const existingRecords = cache.readQuery({ query: gql(listRecordss) }); // Write updated list back to cache (new record first) cache.writeQuery({ query: gql(listRecordss), data: { listRecordss: { ...existingRecords.listRecordss, items: [createRecords, ...existingRecords.listRecordss.items] } } }); } }); // Clear input field after successful mutation this.setState({ Record: '' }); console.log("Record added successfully!"); } catch (err) { console.error("Error adding record:", err); } }
3. Why This Works
- The
Connectcomponent now directly feeds data to MUI-Datatables, so any cache updates (from mutation or subscription) trigger an immediate table re-render. - The mutation's
updatefunction ensures the query cache is refreshed right after the mutation succeeds, so the table updates instantly without waiting for the subscription. - The subscription's
onSubscriptionMsgkeeps the cache in sync if new records are added from other sources (not just your component's mutation).
Bonus: Clean Up Redundant Code
You can remove the commented-out subscrip() function—since we're using Connect to handle subscriptions, that manual subscription code is redundant and could cause state conflicts.
内容的提问来源于stack exchange,提问作者jibidijib

