- Notifications
You must be signed in to change notification settings - Fork8
Query library for mobx-state-tree
License
NotificationsYou must be signed in to change notification settings
ConrabOpto/mst-query
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Query library for mobx-state-tree
- Automatic Normalization
- Garbage Collection
- Infinite Scroll + Pagination Queries
- Optimistic Mutations
- Request Argument Type Validation
- Abort Requests
- Generate Models From Graphql Schema
First, create a query...
import{createQuery,createModelStore}from'mst-query';constMessageQuery=createQuery('MessageQuery',{data:types.reference(MessageModel),request:types.model({id:types.string}),endpoint({ request}){returnfetch(`messages/${request.id}`).then((res)=>res.json());},});
...then use the query in a React component!
constMesssageView=observer((props)=>{const{ id, messageStore}=props;const{ data, error, isLoading}=useQuery(messageStore.messageQuery,{request:{ id},});if(error){return<div>An error occured...</div>;}if(!data){return<div>Loading...</div>;}return<div>{data.message}</div>;});
npm install --save mst-query mobx-state-treeimport{createModelStore,createRootStore,QueryClient,createContext}from'mst-query';constMessageQuery=createQuery('MessageQuery',{data:types.reference(MessageModel),request:types.model({id:types.string}),endpoint({ request}){returnfetch(`messages/${request.id}`).then((res)=>res.json());},});constMessageStore=createModelStore('MessageStore',MessageModel).props({messageQuery:types.optional(MessageQuery,{}),});constRootStore=createRootStore({messageStore:types.optional(MessageStore,{}),});constqueryClient=newQueryClient({ RootStore});const{ QueryClientProvider, useRootStore}=createContext(queryClient);functionApp(){return(<QueryClientProvider><Messages/></QueryClientProvider>);}
import{types}from'mobx-state-tree';import{createQuery}from'mst-query';import{MessageModel}from'./models';import{getItems}from'./api';constMessageListQuery=createQuery('MessageListQuery',{data:types.array(types.reference(MessageModel)),request:types.model({filter:''}),endpoint({ request}){returnfetch(`messages?filter=${request.filter}`).then((res)=>res.json());},});
import{useQuery}from'mst-query';import{observer}from'mobx-react';import{MessageQuery}from'./MessageQuery';constMesssageView=observer((props)=>{const{ id, snapshot, result}=props;constrootStore=useRootStore();const{ data, error, isLoading, isFetched, isRefetching, isFetchingMore, query, refetch, cachedAt,}=useQuery(rootStore.messageStore.messageQuery,{data:snapshot,request:{ id},enabled:!!id,onError(data,self){},staleTime:0,});if(error){return<div>An error occured...</div>;}if(isLoading){return<div>Loading...</div>;}return<div>{data.message}</div>;});
import{types}from'mobx-state-tree';import{createInfiniteQuery,RequestModel}from'mst-query';import{MessageModel}from'./models';constMessagesQuery=createInfiniteQuery('MessagesQuery',{data:types.model({items:types.array(types.reference(MessageModel))}),pagination:types.model({offset:types.number,limit:types.number}),endpoint({ request}){returnfetch(`messages?offset=${request.offset}&limit=${request.limit}`).then((res)=>res.json());},});constMessageStore=createModelStore('MessageStore',MessageModel).props({messagesQuery:types.optional(MessagesQuery,{}),});
import{useInfiniteQuery}from'mst-query';import{observer}from'mobx-react';import{MessageListQuery}from'./MessageListQuery';constMesssageListView=observer((props)=>{const[offset,setOffset]=useState(0);const{ data, isFetchingMore, query}=useInfiniteQuery(messageStore.messagesQuery,{request:{filter:''},pagination:{ offset,limit:20},});if(isFetchingMore){return<div>Is fetching more results...</div>;}return(<div>{data.items.map((item)=>(<Message/>))}<buttononClick={()=>setOffset(data.items.length)}>Get more messages</button></div>);});
import{types}from'mobx-state-tree';import{createMutation}from'mst-query';constAddMessageMutation=createMutation('AddMessage',{data:types.reference(MessageModel),request:types.model({message:types.string}),});constMessageStore=createModelStore('MessageStore',MessageModel).props({messagesQuery:types.optional(MessagesQuery,{}),addMessageMutation:types.optional(AddMessageMutation,{}),}).actions((self)=>({afterCreate(){onMutate(self.addMessageMutation,(data)=>{self.messagesQuery.data?.items.push(data);});},}));
import{useMutation}from'mst-query';import{observer}from'mobx-react';import{AddMessageMutation}from'./AddMessageMutation';constAddMessage=observer((props)=>{const{ messageStore}=props;const[message,setMessage]=useState('');const[addMessage,{ isLoading}]=useMutation(messageStore.addMessageMutation);return(<div><textareavalue={message}onChange={(ev)=>setMessage(ev.target.value)}/><buttontype="button"disabled={!message.length||isLoading}onClick={()=>{addMessage({request:{ message},optimisticUpdate(){return{id:'temp'+Math.random(), message,};},});setMessage('');}}> Send</button></div>);});
Generate mobx-state-tree models from your graphql schema.
npxmst-query-generatorschema.graphql
The optionstaleTime controls how much time should pass before a cached value needs to be refetched from the server.
rootStore.runGc();
constqueriesWithId=rootStore.getQueries(MessageQuery,(q)=>q.request.id==='message-id');queriesWithId.forEach((q)=>q.refetch());constallMessageMutations=rootStore.getQueries(UpdateMessageMutation);allMessageMutations.forEach((m)=>m.abort());
About
Query library for mobx-state-tree
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
No packages published
Uh oh!
There was an error while loading.Please reload this page.
Contributors3
Uh oh!
There was an error while loading.Please reload this page.