Reducthor is a clean simplification of the redux workflow by letting you describe readable action objects.
Reducthor uses axios as the remote request handler and Immutbale JS to have an immutable state.
Install
npm install reducthor yarn add reducthor
Getting started
A new instance of Reducthor should be instantiated at the beginning, passing a configuration object containing our action descriptors.
This is how a simple action looks like
// actions/setColor.js name: 'SET_COLOR' { return state }
Typescript:
// actions/setColor.ts
And this is how we can configure our Reducthor instance using this action
// reducthor.js const configuration = actions: setColor otherAction const reducthor = configuration
Typescript:
// reducthor.ts
And this is how you can call that action from our Reducthor object to mutate the state.
// index.js // This method was generated based on the configured action name 'SET_COLOR' -> 'setColor'reducthor
Match our ReducthorInstance type with the generated functions (typescript)
Since Reducthor is going to generate functions on the fly we should extend our ReducthorInstance interface if we want typescript to be aware of them.
// reducthor.ts /////// Important// extend the ReducthorInstance interface /////// Important// export as the new interface
Request actions
This is a really useful type of action, it will perform a request to the specified path, method and params and then let us use the response to mutate our state.
Lets get a list of posts
// actions/getPosts.js name: 'GET_POSTS' type: 'request' path: '/posts' method: 'get' { const posts = responsedata return state }
Typescript:
// actions/getPosts.ts
We can configure a base URL in our Rethuctor object.
// reducthor.js const configuration = baseURL: 'api.postworld.com' actions: getPosts const reducthor = configuration
Typescript:
// reducthor.ts const configuration: ReducthorConfiguration = baseURL: 'api.postworld.com' actions: getPosts const reducthor: ReducthorInstance = configuration
Now we call the request action through our Reducthor instance and since we specified the mehtod
as get
we can pass some query params as the first argument of the generated function.
// index.js reducthor
All the request action callbacks
The request action has several useful callbacks for every event the request is coming through where we can mutate the state as our convenience.
// actions/getPosts.js name: 'GET_POSTS' type: 'request' path: '/posts' method: 'get' state // At the moment we call the action from the reducthor object state // The request was successful state // The request returned with some error status number state // axios can provide this event sometimes state // axios can provide this event sometimes state // This happens at last either with a successfull request or not
Typescript:
// actions/getPosts.ts }
Dynamic path
You can specify dynamic paths that should be built on the fly. Like probably you need the path to contain the id of a specific post.
// actions/getPost.js name: 'GET_POST' type: 'request' path: '/post/:id' // the id will be set from the action call method: 'get' { const posts = responsedata return state }
// index.js // The first variable in the path is the first argument in the callreducthor
Private request actions
If the remote server needs some kind of authentication through the request headers you can set the auth configuration.
// reducthor.js const configuration = baseURL: 'api.postworld.com' authConfig: header: 'Authentication' // It can be any header you want default is 'Authentication' token: 'sometoken' actions: getPosts const reducthor = configuration
Just set the action as private
to use the header in the request
// actions/getPost.js name: 'GET_POST' type: 'request' path: '/post/:id' method: 'get' private: true { const posts = responsedata return state }
Send multipart/form-data
If you need to upload files to your server, you need to encode the request using multypart/formdata content type, for this you just need to set useMultyPartForm
in your action.
// actions/getPost.js name: 'GET_POST' type: 'request' path: '/post/:id' method: 'get' private: true useMultyPartForm: true // here { const posts = responsedata return state }
Set the auth configuration any time
If you need to specify authentication at any point you can use the configAuth
method.
// index.js reducthor
Using with react-redux
If you are using react-redux to handle state from inside components you can use Reducthor to replace the mapToDispatch approach.
Just set the provider store using the Reacthor store property
const rootElement = documentReactDOM
And connect your components as you wold normally do
{ reducthor } //... const mapStateToProps = { return counter: statecounter } mapStateToPropsCounter
Use a multy reducer store
If you like to use a multy-reducer kind of store you can specify actions in the configuration to follow this pattern.
// reducthor.js const configuration = baseURL: 'api.postworld.com' actions: posts: getPosts users: getUsers const reducthor = configuration
Now action calls are separated by reducer "namespaces"
// index.js reducthorpostsreducthorusers
Initial state and middleware
You can always pass an initial state through the Reducthor configuration and some custom middleware
// reducthor.js const configuration = baseURL: 'api.postworld.com' initialState: Immutable middleware: customMiddleware customMiddleware2 actions: getPosts const reducthor = configuration
Use with redux-devtools-extension
If you would like to use redux-devtools-extension to debug your redux state you can pass the composeWithDevTools function to through the configuration.
// reducthor.js const configuration = baseURL: 'api.postworld.com' composeWithDevTools: composeWithDevTools actions: getPosts const reducthor = configuration
Contributions
PRs are welcome
Lisence
MIT