Redux tide
Simple library for helping created redux-normalized state.
ActionCreator + ActionSelector, reducers are created automatically
Table of Contents
- Features
- Overview
- Examples
- Installation
- Usage
- Action
- Reducer
- Middleware
- Selector
- Contributions
- Changelog
- License
Motivation
You don't need to create reducers for rest-api data
You should create reducers only for business front-end logic
Features
- Simple actionCreator for any of your async library
- Normalization state
- Auto create reducers
- Simple single selector for all your actions
Overview
Redux-Tide - Do not force you to use only it,
This is a small library helping you create normalization, actions, reducers and selector
You can use it with any of other libraries
You can add redux tide in any even old/new project
Redux tide - it's concept for save your backend data, normalize, and selector for it
┌───────────┐
│ Some │
│Reducers...│ ┌──────────┐
└───────────┘ │ Some │ ┌───────────┐
╔═══════════╗ │ Selector │ │ Some │
╔════════╗ ┌────────────┐ ┌────────┐┌▶║ Actions ║ └──────────┘ ┌─▶│ Component │
║ Action ╠──▶ Async Rest ├──▶Response├┤ ║ Meta ╠─┐ │ └───────────┘
╚════════╝ └────────────┘ └────────┘│ ╚═══════════╝ │ ╔══════════╗ │
│ ╔═══════════╗ ├─▶║ Selector ╠─┘
│ ║Normalized ║ │ ╚══════════╝
└▶║ Data ║─┘
╚═══════════╝
Examples
blog - using with axios and REST api
blog-source - blog demo source code
different-entity-id-example
different-entity-id-source
merged-actions-data-example
merged-actions-data-source
Installation
To install the stable version:
npm install redux-tide --save
Complementary Packages
Your project should have normalizr, redux, react-redux, redux-thunk
npm install normalizr --save
npm install redux --save
npm install react-redux --save
npm install redux-thunk --save
Discussion
You can connect to Gitter chat room
Usage
- You might install library
npm install redux-tide --save
-
Install normalizr, redux, react-redux, redux-thunk, you can use help Complementary Packages
-
Define entity-schema
// entity-schema.jsconst postsSchema = 'posts'const commentsSchema = 'comments'postsSchemacommentsSchemaconst appSchema =commentsSchemapostsSchema -
Modify your store.js file
// store.js;;// required// not required// your storeinitialStatecomposedEnhancers -
Ready! Now you can use it. Create action
Discussion
You can connect to Gitter chat room
Action
Example of RestApi class source
You can look entity-schema.js example from Usage section
;; /*** createAction argumnents** @param* @param* @param* @param **/ // simple actionconst getAllPosts = // warning, please read "Create one action for different entity id" sectionconst getPostById = // warning, please read "Create one action for different entity id" sectionconst delPostById = // warning, please read "Create one action for different entity id" sectionconst updatePostById = const createNewPost = // basic redux action can be useconst openEditPost = { return type:OPEN_EDIT postId }
How to reset action store data?
When you need to force a clear state of action, please use
OR
How to use one action with array of connected components ?
Please read Create one action for different entity id section and Other options to create an action
And look examples:
different-entity-id-example
different-entity-id-source
Create one action for different entity id
If you want to create 1 action get || post || put || delete
for work with single entity but multiple entity ids, for example: GET post/:postId
You should be use action.withPrefix method - it's generate new uniq action id and new uniq action reducer state
For details you can look example:
different-entity-id-example
different-entity-id-source
if you dont't make it - your next call dispatch(getPostById(nextPostId))
overwrite your preview call data dispatch(getPostById(prevPostId))
// actions.js;; // write main actionconst getPostById = // component.js;; // WRONG connect! // your selector does not have uniq post Id, so data is rewrited { // your selector does not have uniq post Id, so data is rewrited }SomeComponent // CORRECT connect// you can use this connect with different postId // selector get state of getPostById but reducer key named with postId { // action call getPostById but dispatch TYPE make with prefix postId }SomeComponent // common-component.js { return<PostFormComponent postId=thispropspostId/> }
Selector
;
{String} actionId - your action id
{*} sourceResult - your source response from server (not mapped response)
{String} status - pending|success|error
{Number} time - timestamp of action
{Boolean} hasError - has error or not
{String} errorText - text of error
{Boolean} isFetching - status === 'pending'
{Object|Array} payload - denormalized response for current action
{Object|Array} prevPayload - denormalized previous response
;; // single selector function for all your actions SomeComponent table: state props SomeComponent // create custom selectorsconst makeGetMergedActionData = { return
Middleware
; const createNewPostActionId = createNewPost // delete post using with prefix (post id query parameter), so need check parentActionIdconst delPostByIdParentActionId = delPostById // action id if you called delPostById.withPrefix(postId), where postId === 5const delPostId5ActionId = delPostById const middleware = { const result = // we used action delPostById with prefix postId // for example dispatch(delPostById.withPrefix(postId)(postId) // so, actionId has postId in actionId // and if you want track all calls with any postId you hould used parentActionId property // parentActionId - it's actionId from action which was called .withPrefix(*) // so if you called delPostById.withPrefix()..., parrent action id - it's action id delPostById }
Other options to create an action
.withPrefix
, .withName
, .clone
methods?
How to use For details you can look example:
different-entity-id-example
different-entity-id-source
This methods returns same action
But generate new uniq dispatch type and new uniq action state
You should be call .withPrefix
, .withName
, .clone
when you are dispatch event and use getActionData
// And this methods can chain callsconst getUserAction = // action type id and state key name includes user + userId // OR // AND selector
Custom server response mapper
// calling url 'user' but replace backend success response to resp.data// You always can be get source response data // from selector getActionData property sourceResultconst getUserAction =
Call dispatch or getState in query builder method
// you can pass multi level functions or promises // (args) => (dispatch, getState) => (dispatch, getState) => (dispatch, getState) => ...// calling url 'user/${userId}' const getUserAction =
Whats else?
// actions.js const get = {// returns Promise ajax call} // simple action used custom method for getting dataconst getUserAction = // if you want to best action store name in redux, // you should used this pattern// calling url 'user/${userId}'const getUserAction = // calling url 'user/${userId}' // and post data (if you are using axios) {name, phone, email}const getUserAction = // you can pass multi level functions or promises // (args) => (dispatch, getState) => (dispatch, getState) => (dispatch, getState) => ...// calling url 'user/${userId}'const getUserAction = // calling url 'user' but replace backend success response to resp.dataconst getUserAction = // using with multiple entity ids (make two action ids and stores from simgle action)const getUserByIdAction = // ... const UserContainer =
Additional information, "createAction" public methods
// when you did action, you can use action public methods const getAllPosts = // you can call: // getAllPosts.type()// getAllPosts.getEntityId(postObj)// getAllPosts.getSchema() // getAllPosts.clone()// getAllPosts.withPrefix(customPrefixId) // customPrefixId might be postId // getAllPosts.withName(yourCustomName)// getAllPosts.empty()
For details, please look source
Contributions
Use GitHub issues for requests.
I actively welcome pull requests; learn how to contribute.
Changelog
License
MIT