cs_code
cs_code

Reputation: 1

refetch in react query not works

const UserList = () => {
  const [keyword, setKeyword] = useState('')

  const { data: users, refetch } = useQuery(['users'], () => getUsersApi(keyword), {
    enabled: false,
  })

  // fetching inital users but not works
  useEffect(() => {
    refetch()
  }, [])

  return (
    <div>
      <div>
        <input type="text" onChange={e => setKeyword(e.target.value)} />
        <button onClick={() => refetch()}>Search Users</button>
      </div>
      <ul>
        {users?.map(({ id, name }) => {
          return <li key={id}>{name}</li>
        })}
      </ul>
    </div>
  )
}

I created user list page with react and react query

expected result:

  1. fetch users when page loaded

  2. just send the request only when search button clicked, not every time the input value changes

Upvotes: 0

Views: 474

Answers (1)

Chad S.
Chad S.

Reputation: 6631

const UserList = () => {
  const [keyword, setKeyword] = useState('')

  const { isLoading, data: users } = useQuery(
    ['users', { searchTerm: keyword }], 
    ({queryKey: [, { searchTerm }] }) => getUsersApi(searchTerm)
  );

  return (
    <div>
      <div>
        <input type="text" onChange={e => setKeyword(e.target.value)} />
        <button onClick={() => refetch}>Search Users</button>
      </div>
      { !isLoading && (<ul>
        {users?.map(({ id, name }) => {
          return <li key={id}>{name}</li>
        })}
      </ul>)}
    </div>
  )
}

This is the correct way to structure your query. The param you're sending to the API as the keyword needs to be part of the queryKey in order for the caching system to understand when to re-fetch.

You should not be using a useEffect for this.

Upvotes: 2

Related Questions