如何获取Pinia Store最新状态并传入wagmi异步函数?
问题描述
我创建了一个简单的Pinia计数器store,计数器更新时页面能正常显示最新数值,但在调用wagmi的useContractWrite函数时,无法获取到计数器的最新状态,传入的始终是初始值0。尝试使用getter函数(如const currentCount = counterStore.getCount)还会导致应用崩溃。请问如何正确获取Pinia Store的最新状态,并将其传入wagmi的异步函数中?
附相关代码
count.ts(Pinia store)
export const useCounterStore = defineStore('counter', { state: () => { return { count: 0 } }, actions: { increment() { return this.count++ }, decrement() { return this.count-- } }, getters: { getCount() { return this } } });
page.vue
<template> <div> <button @click="counterStore.increment">+</button> <p>{{ counterStore.count }}</p> <button @click="counterStore.decrement" :disabled="counterStore.count == 0">-</button> <button v-if="user.isConnected" @click="() => write()">Mint</button> <p v-else="" @click="user.connect">Connect Wallet</p> </div> </template> <script setup> import { useCounterStore } from '#imports' import { useContractWrite } from 'use-wagmi' import { parseEther } from 'ethers'; import { useMyUserStore } from '#imports'; const counterStore = useCounterStore() const user = useMyUserStore() const { data, isLoading, isSuccess, write } = useContractWrite({ address: '0x3E966c216fB0b92664DB70b4217AD15d470fe7AC', abi: [ { inputs: [ { "internalType": "uint256", "name": "amount", "type": "uint256" } ], name: "T2GMint", outputs: [], stateMutability: "payable", type: "function" } ], functionName: 'T2GMint', value: parseEther('0.015'), args: [counterStore.count], //counterStore.count is 0. Using getter function here breaks app account: user.address }) </script>
解决方案
1. 修复Pinia Store的错误Getter
你的getCount getter错误返回了整个store实例,这会导致wagmi解析参数时崩溃。修改为直接返回count值:
// count.ts export const useCounterStore = defineStore('counter', { state: () => ({ count: 0 }), actions: { increment() { this.count++ }, decrement() { if(this.count > 0) this.count-- } // 加判断避免负数 }, getters: { getCount: (state) => state.count // 正确返回count数值 } });
2. 动态传递最新状态到wagmi
useContractWrite的初始化配置只会执行一次,无法跟踪Pinia状态变化。解决方案是使用writeAsync(推荐)或write的动态参数,在调用时实时获取最新count:
修改page.vue的点击逻辑和useContractWrite配置:
<template> <div> <button @click="counterStore.increment">+</button> <p>{{ counterStore.count }}</p> <button @click="counterStore.decrement" :disabled="counterStore.count === 0">-</button> <button v-if="user.isConnected" @click="handleMint">Mint</button> <p v-else @click="user.connect">Connect Wallet</p> </div> </template> <script setup> import { useCounterStore } from '#imports' import { useContractWrite } from 'use-wagmi' import { parseEther } from 'ethers'; import { useMyUserStore } from '#imports'; const counterStore = useCounterStore() const user = useMyUserStore() // 初始化时不传入args,留空 const { data, isLoading, isSuccess, writeAsync } = useContractWrite({ address: '0x3E966c216fB0b92664DB70b4217AD15d470fe7AC', abi: [ { inputs: [{ internalType: "uint256", name: "amount", type: "uint256" }], name: "T2GMint", outputs: [], stateMutability: "payable", type: "function" } ], functionName: 'T2GMint', value: parseEther('0.015'), account: user.address }) // 点击时动态传入最新count const handleMint = async () => { if (counterStore.count === 0) return; // 避免 mint 0 数量 try { await writeAsync({ args: [counterStore.count] // 每次调用都取最新状态 }) } catch (err) { console.error('Mint失败:', err) } } </script>
3. 原理说明
useContractWrite的配置对象在组件挂载时就完成求值,初始counterStore.count为0,之后不会自动更新。- 通过
writeAsync动态传参,可以在每次点击时获取最新的Pinia状态,确保传入正确的数值。
内容的提问来源于stack exchange,提问作者Meltxx
相关产品推荐
相关产品推荐

