Skip to content

Instantly share code, notes, and snippets.

@crobinson42
Created July 8, 2019 16:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save crobinson42/b30fe224b8c26e07f3fdac43a35f7342 to your computer and use it in GitHub Desktop.
Save crobinson42/b30fe224b8c26e07f3fdac43a35f7342 to your computer and use it in GitHub Desktop.
JS-Data React Hook useStoreQuery(mapperName, query)
import React from 'react'
import useStoreQuery from './useStoreQuery'
const ActiveUsers = ({ storeQuery, storeQueryLoading }) => {
const { users, loading } = useStoreQuery('users', { where: { active: true } })
return (
<div>{loading ? 'Loading...' : `${users.length} active users found`}</div>
)
}
export default ActiveUsers
import React, { useEffect, useReducer } from 'react'
import axios from 'axios'
import models from './models'
import deepEqual from 'fast-deep-equal'
const httpClient = axios.create({
baseURL: 'http://api.example.com',
})
const store = models.browser.configHttp({ httpClient })
function reducer(state, action) {
switch (action.type) {
case 'set_data':
return { ...state, data: action.payload, loading: false };
case 'fetch_data':
return { ...state, loading: true, prevQuery: action.payload };
default:
return state
}
}
const useStoreQuery = (modelName, query) => {
const [state, dispatch] = useReducer(reducer, { data: undefined, loading: true, prevQuery: undefined })
useEffect(() => {
const run = async () => {
if (dispatch)
dispatch({ type: 'fetch_data', payload: query })
let op
if (typeof query === 'object') op = 'findAll'
else if (typeof query === 'string') op = 'find'
else
throw new Error(
`useStoreQuery model query should return an object or string, ${modelName} received ${typeof query}`,
)
if (!store[modelName])
throw new Error(
`useStoreQuery modelName "${modelName}" not found on store`,
)
console.log(`useStoreQuery(${modelName}, ${JSON.stringify(query || {})})`)
store[modelName][op]
.call(store, query)
.catch(err => {
console.log(`useStoreQuery ${modelName}#${op} err`, err)
return op === 'findAll' ? [] : undefined
})
.then(result => {
if (dispatch)
dispatch({ type: 'set_data', payload: result })
})
}
if (!deepEqual(query, state.prevQuery) && Boolean(query))
run()
}, [modelName, query])
return {
[modelName]: state.data,
loading: state.loading,
}
}
export default useStoreQuery
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment