I have a really simple component using Connect
from aws-amplify-react
const EmployeeExpensesTable = () => {
const [user, setUser] = useState(null)
useEffect(() => { Auth.currentAuthenticatedUser().then(user => setUser(user)) }, [])
console.log(user)
if(!user) { return null }
return (
<Connect
query={graphqlOperation(queries.listTransactions, { owner: user.username })}
subscription={graphqlOperation(subscriptions.onCreateTransaction, { owner: user.username })}
onSubscriptionMsg={(prev, { onCreateTransaction }) => {
console.log('oncreatetransaction:', onCreateTransaction)
console.log('prev', prev)
return onCreateTransaction
}}
>
{
({ data: { listTransactions }, loading, errors }) => {
console.log('transactions', listTransactions)
if (errors.length) return (<h3>Error</h3>)
if (loading || !listTransactions) return (<p>loading...</p>)
return (<core.components.Table data={listTransactions.items} />)
}
}
</Connect>
)
}
export default EmployeeExpensesTable
I have an external ETL process that adds transactions to the DynamoDB table. The subscription is firing and my oncreatetransaction
message is being displayed with the new data, and the Connect
component re-renders, but it renders using it's original data, not the new data. What am I doing wrong?
Turns out that onSubscriptionMsg
is like the reducer for the Connect
component's state. You are given the previous value and the new value to the function and you need to return the new state.
onSubscriptionMsg={(prev, data) => ({
listTransactions: {
items: [...prev.listTransactions.items.slice(-9), data.onCreateTransaction ]
}
})
The above works great for me. The .slice(-9)
is because I only care about the last 10 rows that were added.