Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Store data from useQuery with useState

I'm using React hooks both to fetch GraphQL data with react-apollo and to store local state:

const [userData, setUserData] = useState({})
const { loading, error, data } = useQuery(USER_QUERY)

However, I'm wondering how to store data to userData. Is this how it's supposed to work:

useEffect(() => {
  setUserData(data)
}, [Object.entries(data).length])
like image 863
Fellow Stranger Avatar asked Aug 20 '19 15:08

Fellow Stranger


3 Answers

What are you trying to do with the returned data that you are unable to accomplish by simply using it as destructured from the query hook? In most use cases it can be used immediately, as it will update itself when refetched.

If it is necessary (and it could be), as the other answer says, the useEffect hook you posted should work, but I would replace the dependency with simply data, to prevent an edge case where the response has an equal length consisting of different data and does not update:

useEffect(() => {
  setUserData(data)
}, [data])
like image 197
Chris B. Avatar answered Nov 09 '22 14:11

Chris B.


Looks like what you have probably works. There is also a onCompleted option available in the options parameter. it takes a callback of type:

(data: TData | {}) => void

so this is another way of doing it:

const { loading, error, data } = useQuery(USER_QUERY, {onCompleted: setUserData})
like image 28
thathat Avatar answered Nov 09 '22 13:11

thathat


I think something like this would work - you will need to create the initial state with useState, could be empty array and then onComplete in the useQuery would setTranscationsData... it is triggered every render when state or props change. Could of course add an inital state inside useState which insn't an empty array.

const [transactionsData, setTransactionsData] = React.useState([]);

const { error, data } = useQuery(GET_TRANSACTIONS, {
  onCompleted: () => {
    setTransactionsData(data.transactions);
  },
});

another example

  const [getLegalStatement] = useLazyQuery(GET_LEGAL_STATEMENT, {
    fetchPolicy: 'network-only',
    onCompleted: (data) => {
      setTempLegalStatement(data.getLegalStatement);
    },
    onError: () => {
      setTempLegalStatement({
        consentedLegalStatementHash: '',
        consentedSuppliersHash: '',
        statement: '',
        suppliersModal: '',
      });
      setTimeout(() => {
        setRefetchNeeded(true);
      }, 10000);
    },
  });
like image 3
Jeremy Avatar answered Nov 09 '22 13:11

Jeremy