React Parse
React Parse include 3 data provider components, to make the life even easier and let you get a collection from the server in less than 1 minute with the ability to filter result, create a new document and more...
Helpful only for react and react-native apps with parse server and redux as management
Demo
Table of content
Installation
How to install
Install with NPM:
npm i react-parse --save
1 - Inside your root component:
Set react-parse inside your root component:
import
After the user logs in - set the user's token:
reactParseConfig.setSessionToken
After the user logs out - clear the token:
parseReducer
to your your rootReducer
2 - With Redux - add import
parseWatcher
to your root saga
3 - With Redux-Saga, add import
Now let see how you can fetch your products without writing any new action, reducer, saga worker..
Examples
FetchCollectionExample
Fetch collection data with data provider component
import FetchCollection from 'react-parse'const TARGET_NAME = 'activeProducts' Component { return <FetchCollection = = = ='Dan' = /> }/*MyTable will get props from FetchCollection, MyTable props will be:const {schemaName, targetName, userName, fetchProps} = this.propsconst {data,error,status,info,isLoading,refresh,deleteDoc,put,post} = fetchProps*/
We can do the same thing with react-parse actions
CollectionActionsExample
Get Products from server by using collections actions and selectors
import selectors actions from 'react-parse'; const TARGET_NAME = 'ProductList'Component { actionscollectionActions; } { const products isLoading = thisprops; return <div....);} } = () => return products: selectors isLoading: selectors ;
Actions
How to use
import actions from react-parse
import collectionActions cloudCodeActions documentActions from 'react-parse';
inside your component you can call an action like that:
documentActions
all the action are wrapped with dispatch then you didn't need to bind a dispatch to call an action.
If you want to use:
- Call the action with dispatch
- Use bindActionCreators
- Put an action from saga
You need to use action without our dispatch wrapper. for this, you need the call action with prefix pure_
For example-
// my-saga-file.jsimport put select from 'redux-saga/effects';import documentActions from 'react-parse'; { ;}
payload
action payload options
key | type | info |
---|---|---|
schemaName | string | db schemaName |
targetName | string | target to save the response from server |
query | object | http://docs.parseplatform.org/rest/guide/#queries |
limit | number | number of documents to include in each query |
skip | number | number of documents to skip |
include | string | pointer to include, example: 'Product,User' |
keys | string | keys to include, , example: 'firstName,LastName' |
enableCount | boolean | set true to count objects in the collection |
autoRefresh | boolean | set to to refresh collection data on one of the document change from one of the document actions from the collectionActions |
documentId | string | db document id |
data | object | |
functionName | string | cloud code function name |
params | object | cloud code params |
digToData | string | string that help us find your data, default is 'data.result' |
logger | object | pass to your Logger relevant info |
filesIncluded | boolean | set true if your data include files to upload |
fileValueHandler | function | pass function that will get the new file URL if you didn't want to save it as File object |
dispatchId | string | optional, you can pass some unique key to help you follow specific query status |
boomerang | any | You can transfer anything and it will come back to you with data providers callbacks. this is just data that can help you manage your stuff |
onSuccess | function | onSuccess will be called on query end successfully with this parameter ({type, action, status, res}) *res is the network response |
onError | function | onError will be called on query end successfully with this parameter ({type, action, status, res}) *res is the network response |
import all actions
import actions from 'react-parse';// use like that: actions.collectionActions.fetchData(...)
collectionActions:
import collectionActions from 'react-parse';// use like that: collectionActions.fetchData(...)
-
GET collection from server: fetchData({schemaName, targetName, query, limit, skip, include, keys, enableCount, logger, dispatchId, boomerang})
-
POST document postDoc({schemaName, targetName, data, autoRefresh, logger, filesIncluded, fileValueHandler, dispatchId, boomerang})
-
PUT document putDoc({schemaName, targetName, objectId, data, autoRefresh, logger, filesIncluded, fileValueHandler, dispatchId, boomerang})
-
DELETE document deleteDoc({schemaName, targetName, objectId, autoRefresh, logger, dispatchId, boomerang})
-
Refresh your data refreshCollection({targetName, dispatchId})
-
Clean collection from your store: cleanData({targetName})
-
Clean all collections from your store: cleanCollections()
DocumentActions:
import
-
GET Document from server: fetchData({schemaName, targetName, objectId, include, keys, logger, dispatchId, boomerang})
-
POST document postDoc({schemaName, targetName, data, logger, filesIncluded, fileValueHandler, dispatchId, boomerang})
-
PUT document putDoc({schemaName, targetName, objectId, data, logger, filesIncluded, fileValueHandler, dispatchId, boomerang})
-
DELETE document deleteDoc({schemaName, targetName, objectId, logger, dispatchId, boomerang})
-
Update local data updateField({targetName, key, value, logger})
-
Update local data updateFields({targetName, data, logger})
-
Clean document from your store: cleanData({targetName})
-
Clean all documents from your store: cleanDocuments()
CloudCodeActions:
import
-
GET Document from server: fetchData({functionName, targetName, params, digToData, logger, dispatchId, boomerang})
-
Clean cloudCode from your store: cleanData({targetName})
-
Clean all codes code from your store: cleanCloudsCode()
Selectors
import {selectors} from 'react-parse'
CollectionSelectors
- selectors.selectCollections(state) // return you all the collection from state.parse.collections
- selectors.selectCollectionData(state, 'TARGET_NAME') // return you the data by targetName
- selectors.selectCollectionLoading(state, 'TARGET_NAME') // return true if query is loading
- selectors.selectCollectionInfo(state, 'TARGET_NAME') // return query info by targetName
- selectors.selectCollectionStatus(state, 'TARGET_NAME') // return query status by targetName
- selectors.selectCollectionError(state, 'TARGET_NAME') // return query error by targetName
- selectors.selectCollectionCount(state, 'TARGET_NAME') // return the quantity of results by targetName
- selectors.selectCollectionDispatchId(state, 'TARGET_NAME') // return the dispatchId of the current/last query
- selectors.selectCollectionBoomerang(state, 'TARGET_NAME') // return your last Boomerang data
DocumentSelectors
- selectors.selectDocuments(state)
- selectors.selectDocumentData(state, 'TARGET_NAME')
- selectors.selectDocumentLoading(state, 'TARGET_NAME')
- selectors.selectDocumentInfo(state, 'TARGET_NAME')
- selectors.selectDocumentStatus(state, 'TARGET_NAME')
- selectors.selectDocumentError(state, 'TARGET_NAME')
- selectors.selectDocumentDispatchId(state, 'TARGET_NAME')
- selectors.selectDocumentBoomerang(state, 'TARGET_NAME')
CloudCodeSelectors
- selectors.selectCloudCodes(state)
- selectors.selectCloudCodeData(state, 'TARGET_NAME')
- selectors.selectCloudCodeLoading(state, 'TARGET_NAME')
- selectors.selectCloudCodeInfo(state, 'TARGET_NAME')
- selectors.selectCloudCodeStatus(state, 'TARGET_NAME')
- selectors.selectCloudCodeError(state, 'TARGET_NAME')
- selectors.selectCloudCodeDispatchId(state, 'TARGET_NAME')
dataProviders
Data provider components. Seamlessly bring Parse data into your Component with the ability to POST, PUT, DELETE from your component without connecting your component to store or run any action. all is in your props
FetchProps
Data provider component will render you component with all the props you pass to the dataComponent and with fetchProps object.
fetchProps is the default key but you can set your key, just pass fetchPropsKey inside dataProviders < FetchCollection fetchPropsKey='res'
fetchProps include :
- data - response from the server
- error - error object from query
- status - one of the enum
- info - info about your query {timestamp, query,skip,limit,objectId, ...}
- isLoading- boolean value
- refresh - method, run to refresh data
- fetchProps.refresh()
- cleanData - method, run to clean data from store
- fetchProps.cleanData()
- put- method, run to update the document
- from FetchCollection => fetchProps.put('DOC_OBJECT_ID',{title: 'newTitle', body: 'newBody'},filesIncluded, fileValueHandler, dispatchId)
- from FetchDocument => fetchProps.put({title: 'newTitle', body: 'newBody'},filesIncluded, fileValueHandler, dispatchId, boomerang)
- post- method, run to create document,
- from FetchCollection => fetchProps.post('DOC_OBJECT_ID',{title: 'newTitle', body: 'newBody'},filesIncluded, fileValueHandler, dispatchId, boomerang)
- from FetchDocument => fetchProps.post({title: 'newTitle', body: 'newBody'},filesIncluded, fileValueHandler, dispatchId, boomerang)
- deleteDoc- method, run to delete document,
- from FetchCollection => fetchProps.deleteDoc('DOC_OBJECT_ID', dispatchId, boomerang)
- from FetchDocument => fetchProps.deleteDoc(, dispatchId)
- updateField - method on FetchDocument to update filed in store
- fetchProps.updateField('title', 'new Title)
FetchDocument:
With FetchDocument
you can get specific document by collection name and objectId
import FetchDocument from 'react-parse'...<FetchDocument ='Post' ='LastPost' ='blDxFXA9Wk' = // = // ='title,body,owner' ='Owner' = = = = = // = // = // , = // // = // . = // , ='Dan' // ../>
- if the objectId is empty then use updateField and we save your inputs in the store, then you can use post method from your component and new doc will create for you in the server, the new doc id will be inside info
FetchCollection:
With FetchCollection
you can get list of document by collection name
import FetchCollection from 'react-parse'...<FetchCollection ='Post' ='LastPost' = // = // ='' ='' = = = = = // = // = // , = // // = // //..///# ='' // '-createdAt', = // = // = // = // . // , ='Dan' // />
FetchCloudCode:
With FetchCloudCode
you can get list of document by collection name
import FetchCloudCode from 'react-parse'...<FetchCloudCode ='GetPosts' = // ='GetPostsCloud' = // = // = = // = // = // , = // . // , ='Dan' // />
State
View to Your redux store: we use immutable-js and reselect
parse: collections: myProducts: status: 'FETCH_FINISHED' error: null loading: false data: ... info: schemaName : '' query: ... skip: 0 enableCount: false keys include order limit count timestamp documents: ... cloudCodes: ...
Enum:
import {constants} from 'react-parse'
// FETCH
'FETCH_START','FETCH_FAILED','FETCH_FAILED_NETWORK','FETCH_FINISHED'
// POST
'POST_START','POST_FAILED','POST_FAILED_NETWORK','POST_FINISHED'
// DELETE
'DELETE_START','DELETE_FAILED','DELETE_FAILED_NETWORK','DELETE_FINISHED'
// PUT
'PUT_START','PUT_FAILED','PUT_FAILED_NETWORK','PUT_FINISHED'
Logger
First set the callbacks with setLoggerHandlers in each query your call back will run with => (type, action, status)
- type - one of ['CLOUD_CODE', 'GET', 'POST', 'PUT', 'DELETE']
- action- action object , you can use action.logger to custom call back behavior
- status - one of react-parse status, you can find them in status enum
import {setLoggerHandlers} from 'react-parse'
setLoggerHandlers({
onSuccess: (type, action, status) => {
console.log('Send notification or something else:', type, action, status)
},
onError: (type, action, status) => {
console.log('Send notification or something else:', type, action, status)
}
})
loader
need a global loader?
import {ShowLoader} from 'react-parse'class MyComponent extends React.Component
CleanState
Need to clean the state ?
- Option 1
Add lister to your logout action type:
import {setClearStateActionType} from 'react-parse setClearStateActionType('USER_LOGOUT')
- Option 2
Call react-parse cleanAllState action
import {cleanAllState} from 'react-parse cleanAllState()
- Option 3 dispatch action with this type 'CLEAN_ALL_PARSE_STATE'
# Contribute You can help improving this project sending PRs and helping with issues.