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

custom hook like react query #45

Open
yathink3 opened this issue Nov 13, 2021 · 8 comments
Open

custom hook like react query #45

yathink3 opened this issue Nov 13, 2021 · 8 comments

Comments

@yathink3
Copy link

yathink3 commented Nov 13, 2021

can we create custom hook like react query or redux rtk query @aralroca

@aralroca
Copy link
Collaborator

Something like this?

const { isLoading, error, data } = useQuery('repoData', () =>
     fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res =>
       res.json()
     )
   )

@yathink3
Copy link
Author

yathink3 commented Nov 13, 2021

yes , but same time we need to control over values on store,

i like redux and rtk query , but i had problem like we cant control over rtk query

@aralroca
Copy link
Collaborator

I will think of an alternative to see if it fits. Any implementation proposal will be welcome 😊

@MikeMcElroy
Copy link

For whatever it's worth, I futzed around and made something vaguely like it:

import createStore from "teaful";

// STORE
export const { useStore, getStore, withStore } = createStore({
  data: null,
  loading: true,
  error: null
})

// ACTIONS
export const refresh = () => Promise.resolve()
  .then(() => getStore.loading()[1](true))
  .then(() => fetch('https://picsum.photos/v2/list'))
  .then(x => x.json())
  .then(data => getStore.data()[1](data))
  .catch(error => getStore.error()[1](error))
  .finally(() => getStore.loading()[1](false));

Then in the component consuming it:

import { useStore, refresh } from './store'

export default function App() {
  const [data] = useStore.data()
  const [loading] = useStore.loading()
  const [error] = useStore.error()
  return (
    <>
      <h1>Photo!</h1>
      {loading && <span>LOADING</span>}
      {!loading && !error && <pre>{JSON.stringify(data[10], null, 2)}</pre>}
      <button onClick={() => refresh()}>Refresh picture</button>
    </>
  );
}

And it seems to work about like that.

@MikeMcElroy
Copy link

Granted, this is my first time playing with Teaful, so I'm probably doing a lot wrong, but it seems nicely packaged up.

@aralroca
Copy link
Collaborator

aralroca commented Nov 30, 2021

Thanks @MikeMcElroy! Great implementation 😊

@yathink3 To use a method similar to useQuery for more queries is possible with something like this:

const { useStore } = createStore(initialStore);

function useQuery(key, query) {
  const [field, setField] = useStore[key]()

  useEffect(() => {
    if (field) return
    setField({ isLoading: true })
    query()
      .then(data => setField(s => ({ ...s, data })))
      .catch((error) => setField(s => ({ ...s, error })))
      .finally(() => setField(s => ({ ...s, isLoading: false })))
  }, [])
 
  return field || { isLoading: true }
}

And then inside a components:

const { isLoading, error, data } = useQuery('repoData', () =>
     fetch('https://picsum.photos/v2/list').then(res =>
       res.json()
     )
   )

or after the query:

const [{ isLoading, error, data }] =  useStore.repoData()

or:

const [data] =  useStore.repoData.data()

If you want the useQuery to be inside each createStore:

const { useQuery } = createStore() // Something like this

It can be added as an extra without increasing the size of the library (in the case you do not want this extra).

About extras:

https://github.com/teafuljs/teaful/blob/09b78a04d14e51f827d1e05bf0d184079a7f331e/README.md#addons-and-extras- (Documentation I am updating here)

@aralroca
Copy link
Collaborator

aralroca commented Dec 3, 2021

Note: It would be nice to make an integration with Suspense.

<Suspense fallback="Loading...">
  <ComponentThatUseQuery />
<Suspense/>

ComponentThatUseQuery:

const [data, setData] = useQuery('repoData', () =>
     fetch('https://picsum.photos/v2/list').then(res =>
       res.json()
     )
   )

https://reactjs.org/docs/concurrent-mode-suspense.html

@yathink3
Copy link
Author

yathink3 commented Dec 3, 2021

ya i got it, now teaful is 🚀🚀 with devtools

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

No branches or pull requests

3 participants