Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
immer-reducer
Advanced tools
Create Redux reducers using [Immer](https://github.com/mweststrate/immer)!
Create Redux reducers using Immer!
Typescript friendly too.
Read an introductory blog post here.
npm install immer-reducer
Reducers are defined by extending from the ImmerReducer
class
import {ImmerReducer} from "immer-reducer";
// The class represents the classic switch-case reducer
class MyImmerReducer extends ImmerReducer {
// each method becomes an Action Creator
setFirstName(firstName) {
// State updates are simple as assigning a value to
// the draftState property thanks to Immer
this.draftState.firstName = firstName;
}
setLastName(lastName) {
this.draftState.lastName = lastName;
}
// You can combine methods to a single Action Creator
setName(firstName, lastName) {
this.setFirstName(firstName);
this.setLastName(lastName);
}
}
Generate Action Creators and the actual reducer function for Redux
import {createActionCreators, createReducerFunction} from "immer-reducer";
const ActionCreators = createActionCreators(MyImmerReducer);
const reducerFunction = createReducerFunction(MyImmerReducer);
and create the Redux store
import {createStore} from "redux";
const initialState = {
firstName: "",
lastName: "",
};
const store = createStore(reducerFunction, initialState);
Dispatch some actions
store.dispatch(ActionCreators.setFirstName("Charlie"));
store.dispatch(ActionCreators.setLastName("Brown"));
expect(store.getState().firstName).toEqual("Charlie");
expect(store.getState().lastName).toEqual("Brown");
Under the hood the class is deconstructed to following actions:
{
type: "IMMER_REDUCER:MyImmerReducer#setFirstName",
payload: ["Charlie"],
}
{
type: "IMMER_REDUCER:MyImmerReducer#setLastName",
payload: ["Brown"],
}
So the method names become the Redux Action Types and the method arguments become the action payloads. The reducer function will then match these actions against the class and calls the appropriate methods with the payload array spread to the arguments. But do note that the action format is not part of the public API so don't write any code relying on it. The actions are handled by the generated reducer function.
The generated reducer function executes the methods inside the produce()
function of Immer enabling the terse mutatable style updates.
To integrate for example with the side effects libraries such as
redux-observable and
redux-saga, you can access the
generated action type using the type
property of the action creator
function:
// Get the action name to subscribe to
const setFirstNameActionTypeName = ActionCreators.setFirstName.type;
// Get the action type to have a type safe Epic
type SetFirstNameAction = ReturnType<typeof ActionCreators.setFirstName>;
const setFirstNameEpic: Epic<SetFirstNameAction> = action$ =>
action$
.ofType(setFirstNameActionTypeName)
.pipe(
// action.payload - recognized as string
map(action => action.payload.toUpperCase()),
...
);
This library by no means requires you to use Typescript but it was written specifically Typescript usage in mind because I was unable to find any other libraries that make Redux usage both boilerplate free and 100% type safe. Pretty advanced Typescript sorcery was required and so this library requires Typescript 3.1 or later. But the end results is really simple for the end user.
The Typescript usage does not differ that much from the Javascript usage. Just pass your state type as the type argument for the class
interface State {
// The state can be defined as read only
readonly firstName: string;
readonly lastName: string;
}
class MyImmerReducer extends ImmerReducer<State> {
setFirstName(firstName: string) {
// draftState has the State type but the readonly
// flags are removed here to allow type safe mutation
this.draftState.firstName = firstName;
}
setLastName(lastName: string) {
this.draftState.lastName = lastName;
}
}
The generated ActionsTypes
object now respects the types used in the class
const ActionCreators = createActionCreators(MyImmerReducer);
ActionCreators.setFirstName("Charlie"); // OK
ActionCreators.setFirstName(1); // Type error
ActionCreators.setWAT("Charlie"); // Type error
The reducer function is also typed properly
const reducer = createReducerFunction(MyImmerReducer);
const initialState: State = {
firstName: "",
lastName: "",
};
reducer(initialState, ActionCreators.setFirstName("Charlie")); // OK
reducer(initialState, {type: "WAT"}); // Type error
reducer({wat: "bad state"}, ActionCreators.setFirstName("Charlie")); // Type error
Here's a more complete example with redux-render-prop:
FAQs
Type-safe and terse reducers with Typescript for React Hooks and Redux using [Immer](https://immerjs.github.io/immer/)!
The npm package immer-reducer receives a total of 2,767 weekly downloads. As such, immer-reducer popularity was classified as popular.
We found that immer-reducer demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.