samzmann
samzmann

Reputation: 2566

Reset useLazyQuery after called once

I'm using useLazyQuery to trigger a query on a button click. After the query is called once, the results (data, error, etc) are passed to the component render on each render. This is problematic for example when the user enters new text input to change what caused the error: the error message keeps reapearing. So I would like to "clear" the query (eg. when user types new data into TextInput) so the query results return to there inital state (everything undefined) and the error message goes away.

I can't find any clear way to do this in the Apollo docs, so how could I do that?

(I though of putting the query in the parent component so it does not update on each rerender, but I'd rather not do that)

This is how I have my component currently setup:

import { useLazyQuery } from 'react-apollo'

// ...

const [inputValue, setInputValue] = useState('')

const [getUserIdFromToken, { called, loading, data, error }] = useLazyQuery(deliveryTokenQuery, {
  variables: {
    id: inputValue.toUpperCase(),
  },
})

useEffect(() => {
  if (data && data.deliveryToken) {
    onSuccess({
      userId: data.deliveryToken.vytal_user_id,
      token: inputValue,
    })
  }
}, [data, inputValue, onSuccess])

// this is called on button tap
const submitToken = async () => {
  Keyboard.dismiss()
  getUserIdFromToken()
}

// later in the render...

<TextInput
  onChangeText={(val) => {
    setInputValue(val)
    if (called) {
      // clean/reset query here?  <----------------------
    }
  })
/>

Upvotes: 4

Views: 6463

Answers (1)

samzmann
samzmann

Reputation: 2566

Thanks @xadm for pointing out the solution: I had to give onCompleted and onError callbacks in useLazyQuery options, and pass the variables to the call function, not in useLazyQuery options. In the end the working code looks like this:


const [inputValue, setInputValue] = useState('')
const [codeError, setCodeError] = useState<string | undefined>()

const [getUserIdFromToken, { loading }] = useLazyQuery(deliveryTokenQuery, {
  onCompleted: ({ deliveryToken }) => {
    onSuccess({
      userId: deliveryToken.vytal_user_id,
      token: inputValue,
    })
  },
  onError: (e) => {
    if (e.graphQLErrors &&  e.graphQLErrors[0] === 'DELIVERY_TOKEN_NOT_FOUND') {
      return setCodeError('DELIVERY_TOKEN_NOT_FOUND')
    }
    return setCodeError('UNKNOWN')
  },
})

const submitToken = () => {
  Keyboard.dismiss()
  getUserIdFromToken({
    variables: {
      id: inputValue
    },
  })
}

Upvotes: 6

Related Questions