百科.dev
全部条目AI 编程趋势榜开源项目技术资讯提交条目
登录
< 返回工具列表
R

redux-act

> 编程语言
开源

一个具有主张的库,用于为 Redux 创建操作和减少器

1.5K stars0 点赞2 次浏览
访问官网GitHub

工具介绍

一个具有主张的库,用于为 Redux 创建操作和减少器

redux-act

An opinionated lib to create actions and reducers for Redux. The main goal is to use actions themselves as references inside the reducers rather than string constants.

Install

# NPM
npm install redux-act --save
# Yarn
yarn add redux-act

You can also use a browser friendly compiled file or the minified version from NPM CDN (mostly for online demo / snippets).

Browser support: this lib uses String.prototype.startsWith which is not supported by IE11. Be sure to add a polyfill if you are targeting this browser. Learn more.

Content

  • Usage
  • FAQ
  • Advanced usage
  • API
    • createAction
    • action creator
    • createReducer
    • reducer
    • assignAll
    • bindAll
    • batch
    • disbatch
    • asError
    • types
  • Cookbook
    • Compatibility
    • Adding and removing actions
    • Async actions
    • Enable or disable batch
    • TypeScript
  • Loggers
    • Redux Logger

Usage

Even if there is a function named createAction, it actually creates an action creator according to Redux glossary. It was just a bit overkill to name the function createActionCreator. If you are not sure if something is an action or an action creator, just remember that actions are plain objects while action creators are functions.

…

FAQ

  • Does it work with Redux devtools? Yes.

  • Do reducers work with combineReducers? Of course, they are just normal reducers after all. Remember that according to the combineReducers checks, you will need to provide a default state when creating each reducer before combining them.

  • How does it work? There is not much magic. A generated id is prepended to each action type and will be used inside reducers instead of the string constants used inside Redux by default.

  • Can you show how different it is from writing classic Redux? Sure, you can check both commits to update counter example and todomvc example. You can also run both examples with npm install && npm start inside each folder.

  • Why having two syntax to create reducers? The one with only a map of action => reduce function doesn't allow much. This is why the other one is here, in case you would need a small state inside the reducer, having something similar as an actor, or whatever you feel like. Also, one of the syntax is ES6 only.

  • Inside a reducer, why is it (state, payload) => newState rather than (state, action) => newState? You can find more info about that on the createReducer API below, but basically, that's because an action is composed of metadata handled by the lib and your payload. Since you only care about that part, better to have it directly. You can switch back to the full action if necessary of course.

  • Why have you done that? Aren't string constants good enough? I know that the Redux doc states that such magic isn't really good, that saving a few lines of code isn't worth hiding such logic. I can understand that. And don't get me wrong, the main goal of this lib isn't to reduce boilerplate (even if I like that it does) but to use the actions themselves as keys for the reducers rather than strings which are error prone. You never know what the new dev on your project might do... Maybe (s)he will not realize that the new constant (s)he just introduced was already existing and now everything is broken and a wormhole will appear and it will be the end of mankind. Let's prevent that!

Advanced usage

…

API

createAction([description], [payloadReducer], [metaReducer])

Parameters

  • description (string, optional): used by logging and devtools when displaying the action. If this parameter is uppercase only, with underscores and numbers, it will be used as the action type without any generated id. You can use this feature to have serializable actions you can share between client and server.
  • payloadReducer (function, optional): transform multiple arguments as a unique payload.
  • metaReducer (function, optional): transform multiple arguments as a unique metadata object.

Usage

Returns a new action creator. If you specify a description, it will be used by devtools. By default, createAction will return a function and its first argument will be used as the payload when dispatching the action. If you need to support multiple arguments, you need to specify a payload reducer in order to merge all arguments into one unique payload.

// Super simple action
const simpleAction = createAction();
// Better to add a description
const betterAction = createAction('This is better!');
// Support multiple arguments by merging them
const multipleAction = createAction((text, checked) => ({text, checked}))
// Again, better to add a description
const bestAction = createAction('Best. Action. Ever.', (text, checked) => ({text, checked}))
// Serializable action (the description will be used as the unique identifier)
const serializableAction = createAction('SERIALIZABLE_ACTION_42');

action creator

An action creator is basically a function that takes arguments and return an action which has the following format:

  • type: generated id + your description.
  • payload: the data passed when calling the action creator. Will be the first argument of the function except if you specified a payload reducer when creating the action.
  • meta: if you have provided a metaReducer, it will be used to create a metadata object assigned to this key. Otherwise, it's undefined.
  • error: a boolean indicating if the action is an error according to FSA.
const addTodo = createAction('Add todo');
addTodo('content');
// return { type: '[1] Add todo', payload: 'content' }

const editTodo = createAction('Edit todo', (id, content) => ({id, content}));
editTodo(42, 'the answer');
// return { type: '[2] Edit todo', payload: {id: 42, content: 'the answer'} }

const serializeTodo = createAction('SERIALIZE_TODO');
serializeTodo(1);
// return { type: 'SERIALIZE_TODO', payload: 1 }

An action creator has the following methods:

getType()

Return the generated type that will be used by all actions from this action creator. Useful for compatibility purposes.

assignTo(store | dispatch)

Remember that you still need to dispatch those actions. If you already have one or more stores, you can assign the action using the assignTo function. This will mutate the action creator itself. You can pass one store or one dispatch function or an array of any of both.

…

bindTo(store | dispatch)

If you need immutability, you can use bindTo, it will return a new action creator which will automatically dispatch its action.

// If you need more immutability, you can bind them, creating a new action creator
const boundAction = action2.bindTo(store);
action2(); // Not doing anything since not assigned nor bound
// store.getState() === 16
// store2.getState() === -2
boundAction(); // store.getState() === 8

assigned() / bound() / dispatched()

Test the current status of the action creator.

const action = createAction();
action.assigned(); // false, not assigned
action.bound(); // false, not bound
action.dispatched(); // false, test if either assigned or bound

const boundAction = action.bindTo(store);
boundAction.assigned(); // false
boundAction.bound(); // true
boundAction.dispatched(); // true

action.assignTo(store);
action.assigned(); // true
action.bound(); // false
action.dispatched(); // true

raw(...args)

When an action creator is either assigned or bound, it will no longer only return the action object but also dispatch it. In some cases, you will need the action without dispatching it (when batching actions for example). In order to achieve that, you can use the raw method which will return the bare action. You could say that it is exactly the same as the action creator would behave it if wasn't assigned nor bound.

const action = createAction().bindTo(store);
action(1); // store has been updated
action.raw(1); // return the action, store hasn't been updated

asError(...args)*

By default, if your payload is an instance of Error, the action will be tagged as an error. But if you need to use any other kind of payload as an error payload, you can always use this method. It will apply the same payload reducer by setting the error to true.

const actionCreator = createAction(value => {
  if (value > 10) { return new Error('Must be less than 10') }
  return { value: value }
})

const goodAction = actionCreator(5)
goodAction.error // false

const badAction = actionCreator(20)
badAction.error // true

const forcedBadAction = actionCreator.asError(1)
forcedBadAction.error // true

createReducer(handlers, [defaultState])

Parameters

  • handlers (object or function): if object, a map of action to the reduce function. If function, take two attributes: a function to register actions and another one to unregister them. See below.
  • defaultState (anything, optional): the initial state of the reducer. Must not be empty if you plan to use this reducer inside a combineReducers.

Usage

Returns a new reducer. It's kind of the same syntax as the Array.prototype.reduce function. You can specify how to reduce as the first argument and the accumulator, or default state, as the second one. The default state is optional since you can retrieve it from the store when creating it but you should consider always having a default state inside a reducer, especially if you want to use it with combineReducers which make such default state mandatory.

There are two patterns to create a reducer. One is passing an object as a map of action creators to reduce functions. Such functions have the following signature: (previousState, payload) => newState. The other one is using a function factory. Rather than trying to explaining it, just read the following examples.

const increment = createAction();
const add = createAction();

// First pattern
const reducerMap = createReducer({
  [increment]: (state) => state + 1,
  [add]: (state, payload) => state + payload
}, 0);

// Second pattern
const reducerFactory = createReducer(function (on, off) {
  on(increment, (state) => state + 1);
  on(add, (state, payload) => state + payload);
  // 'off' remove support for a specific action
  // See 'Adding and removing actions' section
}, 0);

reducer

Like everything, a reducer is just a function. It takes the current state and an action payload and return the new state. It has the following methods.

options({ payload: boolean, fallback: [handler] })

Since an action is an object with a type, a payload (which is your actual data) and eventually some metadata, all reduce functions directly take the payload as their 2nd argument and the metadata as the 3rd by default rather than the whole action since all other properties are handled by the lib and you shouldn't care about them anyway. If you really need to use the full

GitHub Issues· 6 开放

在 GitHub 查看全部
  • #109

    Typescript: Handler not returning state

    更新于 2021年10月12日
  • #110

    TypeScript: an action with a function with no arguments as payload causes a typing error

    更新于 2020年4月14日
  • #97

    Better Typescript typings

    更新于 2019年5月21日

核心特点

  • •Advanced usage
  • •createAction
  • •action creator
  • •createReducer
  • •assignAll
  • •disbatch
  • •Cookbook
  • •Compatibility
  • •Adding and removing actions
  • •Async actions

> 标签

JavaScriptjavascriptredux

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月17日
分类编程语言
定价开源

> 相关工具

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言