teaful
teaful copied to clipboard
custom hook like react query
can we create custom hook like react query or redux rtk query @aralroca
Something like this?
const { isLoading, error, data } = useQuery('repoData', () =>
fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res =>
res.json()
)
)
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
I will think of an alternative to see if it fits. Any implementation proposal will be welcome 😊
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.
Granted, this is my first time playing with Teaful, so I'm probably doing a lot wrong, but it seems nicely packaged up.
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)
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
ya i got it, now teaful is 🚀🚀 with devtools