Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hooks useMutation and useQuery #642

Closed
wants to merge 11 commits into from

Conversation

jordevo
Copy link
Contributor

@jordevo jordevo commented Dec 7, 2023

These hooks are useful for better state management of data fetching / mutation.

useMutation

Useful when creating, updating or removing data from a source.

Perform a given mutation and update the status of it.

import useQuery from '@s-ui/react-hooks/lib/useMutation/index.js'

const QueryStory = () => {
  const {domain} = useContext(Context)
  const [createAd, {isLoading}] = useMutation(
    () => {
      return domain.get('create_ad_use_case').execute()
    },
    {
      onSuccess: ad => {
        console.log(ad)
      }
    }
  )

  const handleClick = () => {
    createAd()
  }

  return (
    <button onClick={handleClick} isLoading={isLoading}>
      Create
    </button>
  )
}

useQuery

Hook to fetch data from a source and receive a status update.

Basic usage

Perform a given query and update the status of it

import useQuery from '@s-ui/react-hooks/lib/useQuery/index.js'

const QueryStory = () => {
  const {domain} = useContext(Context)
  const {
    isLoading,
    isError,
    data: ads,
    error
  } = useQuery(() => {
    return domain.get('get_ads_use_case').execute()
  })

  if (isLoading) {
    return <span>Loading...</span>
  }

  if (isError) {
    return <span>Error: {error.message}</span>
  }

  // also status === 'success', but "else" logic works, too
  return (
    <ul>
      {ads.map(ad => (
        <li key={ad.id}>{ad.title}</li>
      ))}
    </ul>
  )
}
Initial state

Use initialData prop to avoid executing the query when the component is mounted. Useful when using Server-Side rendering.

import useQuery from '@s-ui/react-hooks/lib/useQuery/index.js'

const QueryStory = ({ads}) => {
  const {domain} = useContext(Context)
  const {data} = useQuery(
    () => {
      return domain.get('get_ads_use_case').execute()
    },
    {initialData: ads}
  )
}
Interval

Execute the query every refetchInterval milliseconds

import useQuery from '@s-ui/react-hooks/lib/useQuery/index.js'

const QueryStory = ({ads}) => {
  const {domain} = useContext(Context)

  const {data} = useQuery(
    () => {
      return domain.get('get_ads_use_case').execute()
    },
    {refetchInterval: 3000}
  )
}
Disabled mount execution

Disable mount fetch assigning isExecuteOnMountDisabled prop to true

import useQuery from '@s-ui/react-hooks/lib/useQuery/index.js'

const QueryStory = ({ads}) => {
  const {domain} = useContext(Context)

  // Wont be executed on mount instead refetch can be used
  const {data, refetch} = useQuery(
    () => {
      return domain.get('get_ads_use_case').execute()
    },
    {isExecuteOnMountDisabled: true}
  )
}

@jordevo jordevo changed the title Feat react hooks use request use query hooks useMutation and useQuery Dec 7, 2023
@jordevo jordevo requested a review from andresz1 December 7, 2023 15:02
@andresin87
Copy link
Member

andresin87 commented Dec 11, 2023

replace isExecuteOnMountDisabled for isExecutedOnMountDisabled ?

noun participle

better name it affirmative:

isExecutedOnMount: true (default)

isExecutedOnMount: false when needed (equivalent toisExecutedOnMountDisabled = true)

Comment on lines +81 to +83
const requestRef = useRef(request)
const onSuccessRef = useRef(onSuccess)
const onErrorRef = useRef(onError)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need to set these props into a ref?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, I guess is to avoid the dependency in the useCallback for the fetch function so it does not get recomputed if the callbacks reference change. But what happens with this internal onSuccessRef if the onSuccess reference changes? Imagine a case where you need to recreate a new onSuccess callback when, for example, the id parameter changes so your callback looks like this: () => console.log(id) and the id comes from the outer scope. Does the onSuccessRef get updated with the new value?

@jordevo
Copy link
Contributor Author

jordevo commented Dec 11, 2023

closing this PR, a wider agreement is required before we come to materialise this

@jordevo jordevo closed this Dec 11, 2023
@jordevo jordevo deleted the feat-react-hooks-use-request-use-query branch December 11, 2023 11:41
}
}, [])

const refresh = useCallback(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If fetch is already memorized, the use of useCallback here might be a downgrade instead of an upgrade in performance. The same for the other functions that only depend on the fetch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants