4

Working with usePrepareContractWrite Dealing with the logical flow

const { config: contractWriteConfig } = usePrepareContractWrite({
    ...contractConfig,
    functionName: 'mint',
    args: [numToMint],
    overrides: {
        value: ethers.utils.parseEther(payment),  //how do I dynamically change this number on the fly to string
      },
  });
const {
    data: mintData,
    write: mintBee,
    isLoading: isMintLoading,
    isSuccess: isMintStarted,
    error: mintError,
  } = useContractWrite(contractWriteConfig);

In short I'm using a handle event for the number to mint. Before I could multiply the numToMint by the cost amount and convert it to string in another function. Now with usePrepareContractWrite() I'm unsure how to approach this as I can't pass arguments to the "mintBee" write function. Any examples are greatly appreciated!

3 Answers 3

1

Basically, @deepak-sharma has got some things right but his useEffect will trigger an infinite loop and we can also make it a bit better by using a useDebounce (as recommended in wagmi's docs).

import * as React from 'react'
import { ethers } from 'ethers'
import { usePrepareContractWrite, useContractWrite } from 'wagmi'

import { useDebounce } from './useDebounce'
import contractConfig from './contract-config'

export default function MintComponent() {
  const [numToMint, setNumToMint] = React.useState(0)
  const [payment, setPayment] = React.useState(0)

  const debouncedNumToMint = useDebounce(numToMint)
  const debouncedPayment = useDebounce(payment)

  const { config: contractWriteConfig } = usePrepareContractWrite({
    ...contractConfig,
    functionName: 'mint',
    args: [debouncedNumToMint],
    overrides: {
      value: ethers.utils.parseEther(debouncedPayment.toString()),
    },
  })

  const { write: mintBee } = useContractWrite(contractWriteConfig)

  return (
    <form
      onSubmit={e => {
        e.preventDefault()
        mintBee?.()
      }}>
      <label htmlFor='payment'>Payment</label>
      <input
        id='payment'
        type='number'
        onChange={e => setPayment(e.target.value)}
        value={debouncedPayment}
      />
      <label htmlFor='numToMint'>Num to mint</label>
      <input
        id='numToMint'
        type='number'
        onChange={e => setNumToMint(e.target.value)}
        value={debouncedNumToMint}
      />

      <button disabled={!mintBee}>Mint</button>
    </form>
  )
}
0

I think this should work because change in state will trigger the hook to rerender.

const [numToMint, setNumToMint] = React.useState()

const { config: contractWriteConfig } = usePrepareContractWrite({
    ...contractConfig,
    functionName: 'mint',
    args: [numToMint],
    overrides: {
        value: ethers.utils.parseEther(payment)
      },
  });

const {
    data: mintData,
    write: mintBee,
    isLoading: isMintLoading,
    isSuccess: isMintStarted,
    error: mintError,
  } = useContractWrite(contractWriteConfig);

React.useEffect(() =>{
    setNumToMint((numToMint * costAmount).toString())
},[numToMint])
0

I found the refetch method from usePrepareContractWrite and this was enough for me to get the last value in my states.

const { config: configRemove, refetch: refetchRemove } =
usePrepareContractWrite({
  address: contractAddress,
  abi: abi.abi,
  functionName: "removeProject",
  from: walletClient?.account?.address,
  args: [removeId.current || 0],
});

I used useRef instead of useState.

You can see my production code here: https://github.com/paulobordignon/portfolio/blob/33ff09448b319065e67db4a5dd4bab792bb8b71d/src/components/organisms/Admin/Admin.tsx

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.