メインコンテンツへスキップ
非公式ベータ版翻訳

このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →

エコシステム

Reduxは小さなライブラリですが、その設計思想とAPIはツールや拡張機能のエコシステムを生み出すよう慎重に選ばれており、コミュニティは多様な有用なアドオン、ライブラリ、ツールを生み出してきました。Reduxを使用するためにこれらのアドオンは必須ではありませんが、機能実装や問題解決を容易にするのに役立ちます。

Redux関連のライブラリ、アドオン、ツールの包括的なカタログについては、Redux Ecosystem Linksリストを参照してください。また、React/Redux Linksリストには、ReactやReduxを学ぶすべての人向けのチュートリアルや有用なリソースが掲載されています。

このページでは、Reduxメンテナーが個人的に評価したものや、コミュニティで広く採用されているRedux関連アドオンの一部をリストアップしています。これら以外のツールも積極的に試してみてください!エコシステムの成長は非常に速く、私たちが全てを確認する時間は限られています。これらは「スタッフのおすすめ」と考え、Reduxで素晴らしいものを作成した場合は遠慮なくPRを提出してください。

目次

ライブラリ統合とバインディング

reduxjs/react-redux
Redux公式のReactバインディング。Reduxチームがメンテナンスしています。

angular-redux/ng-redux
ReduxのためのAngular 1バインディング

ember-redux/ember-redux
ReduxのためのEmberバインディング

glimmer-redux/glimmer-redux
EmberのGlimmerコンポーネントエンジン向けReduxバインディング

tur-nr/polymer-redux
Polymer向けReduxバインディング

lastmjs/redux-store-element カスタムエレメント向けReduxバインディング

リデューサー

リデューサーの結合

ryo33/combineSectionReducers
combineReducersの拡張版。全スライスリデューサーに第三引数としてstateを渡すことが可能。

KodersLab/topologically-combine-reducers
スライス間の依存関係を定義して実行順序やデータ受け渡しを可能にするcombineReducersの変種

var masterReducer = topologicallyCombineReducers(
{ auth, users, todos },
// define the dependency tree
{ auth: ['users'], todos: ['auth'] }
)

リデューサーの合成

acdlite/reduce-reducers
同レベルでのリデューサーの逐次合成を提供

const combinedReducer = combineReducers({ users, posts, comments })
const rootReducer = reduceReducers(combinedReducer, otherTopLevelFeatureReducer)

mhelmer/redux-xforms
合成可能なリデューサートランスフォーマーのコレクション

const createByFilter = (predicate, mapActionToKey) =>
compose(
withInitialState({}), // inject initial state as {}
withFilter(predicate), // let through if action has filterName
updateSlice(mapActionToKey), // update a single key in the state
isolateSlice(mapActionToKey) // run the reducer on a single state slice
)

adrienjt/redux-data-structures
共通データ構造向けリデューサーファクトリ関数: カウンター、マップ、リスト(キュー、スタック)、セット

const myCounter = counter({
incrementActionTypes: ['INCREMENT'],
decrementActionTypes: ['DECREMENT']
})

高階リデューサー

omnidan/redux-undo
手間いらずのundo/redoとアクション履歴をリデューサーに提供

omnidan/redux-ignore
配列やフィルター関数でReduxアクションを無視

omnidan/redux-recycle
特定アクションでReduxステートをリセット

ForbesLindesay/redux-optimist
型に依存しない楽観的更新を可能にするリデューサーエンハンサー

ユーティリティ

reduxjs/reselect
ストアステートから効率的にデータを導出するための合成可能なメモ化セレクター関数を生成

const taxSelector = createSelector(
[subtotalSelector, taxPercentSelector],
(subtotal, taxPercent) => subtotal * (taxPercent / 100)
)

paularmstrong/normalizr
スキーマに基づいてネストしたJSONを正規化

const user = new schema.Entity('users')
const comment = new schema.Entity('comments', { commenter: user })
const article = new schema.Entity('articles', {
author: user,
comments: [comment]
})
const normalizedData = normalize(originalData, article)

planttheidea/selectorator
一般的なセレクター用途向けReselect抽象化レイヤー

const getBarBaz = createSelector(
['foo.bar', 'baz'],
(bar, baz) => `${bar} ${baz}`
)
getBarBaz({ foo: { bar: 'a' }, baz: 'b' }) // "a b"

ストア

変更サブスクリプション

jprichardson/redux-watch
キーパスやセレクターに基づくステート変更の監視

let w = watch(() => mySelector(store.getState()))
store.subscribe(
w((newVal, oldVal) => {
console.log(newval, oldVal)
})
)

ashaffer/redux-subscribe
パスベースのステート変更に対する集中型サブスクリプション

store.dispatch( subscribe("users.byId.abcd", "subscription1", () => {} );

バッチ処理

tappleby/redux-batched-subscribe
サブスクリプション通知をデバウンス可能なストアエンハンサー

const debounceNotify = _.debounce(notify => notify())
const store = configureStore({
reducer,
enhancers: [batchedSubscribe(debounceNotify)]
})

manaflair/redux-batch
アクションの配列ディスパッチを可能にするストアエンハンサー

const store = configureStore({
reducer,
enhancers: existingEnhancersArray => [
reduxBatch,
...existingEnhancersArray,
reduxBatch
]
})
store.dispatch([{ type: 'INCREMENT' }, { type: 'INCREMENT' }])

laysent/redux-batch-actions-enhancer
バッチアクションを受け入れるストアエンハンサー

const store = configureStore({ reducer, enhancers: [batch().enhancer] })
store.dispatch(createAction({ type: 'INCREMENT' }, { type: 'INCREMENT' }))

tshelburne/redux-batched-actions
バッチアクションを処理する高階リデューサー

const store = configureStore({ reducer: enableBatching(rootReducer) })
store.dispatch(batchActions([{ type: 'INCREMENT' }, { type: 'INCREMENT' }]))

永続化

rt2zz/redux-persist
拡張性の高いオプションでReduxストアの永続化と再ハイドレートを実現

const persistConfig = { key: 'root', version: 1, storage }
const persistedReducer = persistReducer(persistConfig, rootReducer)
export const store = configureStore({
reducer: persistedReducer,
middleware: getDefaultMiddleware =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER]
}
})
})
export const persistor = persistStore(store)

react-stack/redux-storage
柔軟なバックエンドを備えたRedux永続化レイヤー

const reducer = storage.reducer(combineReducers(reducers))
const engine = createEngineLocalStorage('my-save-key')
const storageMiddleware = storage.createMiddleware(engine)
const store = configureStore({
reducer,
middleware: getDefaultMiddleware =>
getDefaultMiddleware.concat(storageMiddleware)
})

redux-offline/redux-offline
オフラインファーストアプリ向けの永続化ストア。楽観的UIをサポート

const store = configureStore({ reducer, enhancer: [offline(offlineConfig)] })
store.dispatch({
type: 'FOLLOW_USER_REQUEST',
meta: { offline: { effect: {}, commit: {}, rollback: {} } }
})

イミュータブルデータ

ImmerJS/immer
Proxyを使用した通常の変更コードによるイミュータブルな更新

const nextState = produce(baseState, draftState => {
draftState.push({ todo: 'Tweet about it' })
draftState[1].done = true
})

副作用

広く使われているもの

reduxjs/redux-thunk
dispatchgetStateをパラメータとして受け取る関数をディスパッチ。AJAX呼び出しやその他の非同期処理のための抜け穴として機能

最適な用途: 初心者向け、シンプルな非同期処理、複雑な同期ロジック

function fetchData(someValue) {
return (dispatch, getState) => {
dispatch({type : "REQUEST_STARTED"});

myAjaxLib.post("/someEndpoint", {data : someValue})
.then(response => dispatch({type : "REQUEST_SUCCEEDED", payload : response})
.catch(error => dispatch({type : "REQUEST_FAILED", error : error});
};
}

function addTodosIfAllowed(todoText) {
return (dispatch, getState) => {
const state = getState();

if(state.todos.length < MAX_TODOS) {
dispatch({type : "ADD_TODO", text : todoText});
}
}
}

listenerMiddleware (Redux Toolkit)
listenerMiddlewareは、sagaやobservableのようなより広く使われるRedux非同期ミドルウェアの軽量な代替手段として設計されています。複雑さや概念のレベルではthunkに似ていますが、一般的なsagaの使用パターンを再現するために使用できます

listenerMiddleware.startListening({
matcher: isAnyOf(action1, action2, action3),
effect: (action, listenerApi) => {
const user = selectUserDetails(listenerApi.getState())

const { specialData } = action.meta

analyticsApi.trackUsage(action.type, user, specialData)
}
})

redux-saga/redux-saga
同期処理のようなジェネレーター関数を使用した非同期ロジックの処理。sagaはエフェクトの記述を返し、sagaミドルウェアによって実行され、JSアプリケーションの「バックグラウンドスレッド」のように振る舞います

最適な用途: 複雑な非同期ロジック、分離されたワークフロー

function* fetchData(action) {
const { someValue } = action
try {
const response = yield call(myAjaxLib.post, '/someEndpoint', {
data: someValue
})
yield put({ type: 'REQUEST_SUCCEEDED', payload: response })
} catch (error) {
yield put({ type: 'REQUEST_FAILED', error: error })
}
}

function* addTodosIfAllowed(action) {
const { todoText } = action
const todos = yield select(state => state.todos)

if (todos.length < MAX_TODOS) {
yield put({ type: 'ADD_TODO', text: todoText })
}
}

redux-observable/redux-observable

"epic"と呼ばれるRxJSオブザーバブルチェーンを使用した非同期ロジックの処理。非同期アクションを合成・キャンセルして副作用などを作成

最適な用途: 複雑な非同期ロジック、分離されたワークフロー

const loginRequestEpic = action$ =>
action$
.ofType(LOGIN_REQUEST)
.mergeMap(({ payload: { username, password } }) =>
Observable.from(postLogin(username, password))
.map(loginSuccess)
.catch(loginFailure)
)

const loginSuccessfulEpic = action$ =>
action$
.ofType(LOGIN_SUCCESS)
.delay(2000)
.mergeMap(({ payload: { msg } }) => showMessage(msg))

const rootEpic = combineEpics(loginRequestEpic, loginSuccessfulEpic)

redux-loop/redux-loop

ElmアーキテクチャをReduxに移植したもので、リデューサーからエフェクトを自然かつ純粋に返すことでシーケンス化できます。リデューサーは状態値と副作用の記述の両方を返すようになります

最適な用途: Redux+JSでElmに可能な限り近づけたい場合

export const reducer = (state = {}, action) => {
switch (action.type) {
case ActionType.LOGIN_REQUEST:
const { username, password } = action.payload
return loop(
{ pending: true },
Effect.promise(loginPromise, username, password)
)
case ActionType.LOGIN_SUCCESS:
const { user, msg } = action.payload
return loop(
{ pending: false, user },
Effect.promise(delayMessagePromise, msg, 2000)
)
case ActionType.LOGIN_FAILURE:
return { pending: false, err: action.payload }
default:
return state
}
}

jeffbski/redux-logic

オブザーバブルで構築された副作用ライブラリ。コールバック、プロミス、async/await、オブザーバブルの使用を許可し、アクションの宣言的処理を提供

最適な用途: 高度に分離された非同期ロジック

const loginLogic = createLogic({
type: Actions.LOGIN_REQUEST,

process({ getState, action }, dispatch, done) {
const { username, password } = action.payload

postLogin(username, password)
.then(
({ user, msg }) => {
dispatch(loginSucceeded(user))

setTimeout(() => dispatch(showMessage(msg)), 2000)
},
err => dispatch(loginFailure(err))
)
.then(done)
}
})

プロミス関連

acdlite/redux-promise
プロミスをアクションペイロードとしてディスパッチし、プロミスの解決/拒否時にFSA準拠のアクションをディスパッチ

dispatch({ type: 'FETCH_DATA', payload: myAjaxLib.get('/data') })
// will dispatch either {type : "FETCH_DATA", payload : response} if resolved,
// or dispatch {type : "FETCH_DATA", payload : error, error : true} if rejected

lelandrichardson/redux-pack
ディスパッチの全機能を公開せずに、適切な方向へ導く直感的で宣言的、慣例ベースのプロミス処理

dispatch({type : "FETCH_DATA", payload : myAjaxLib.get("/data") });

// in a reducer:
case "FETCH_DATA": =
return handle(state, action, {
start: prevState => ({
...prevState,
isLoading: true,
fooError: null
}),
finish: prevState => ({ ...prevState, isLoading: false }),
failure: prevState => ({ ...prevState, fooError: payload }),
success: prevState => ({ ...prevState, foo: payload }),
});

ミドルウェア

ネットワーク&ソケット関連

svrcekmichal/redux-axios-middleware
Axiosによるデータ取得と開始/成功/失敗アクションのディスパッチ

export const loadCategories() => ({ type: 'LOAD', payload: { request : { url: '/categories'} } });

agraboso/redux-api-middleware
API呼び出しアクションを読み取り、取得し、FSAをディスパッチ

const fetchUsers = () => ({
[CALL_API]: {
endpoint: 'http://www.example.com/api/users',
method: 'GET',
types: ['REQUEST', 'SUCCESS', 'FAILURE']
}
})

itaylor/redux-socket.io
socket.ioとredux間のオピニオネイテッドなコネクター

const store = configureStore({
reducer,
middleware: getDefaultMiddleware =>
getDefaultMiddleware.concat(socketIoMiddleware)
})
store.dispatch({ type: 'server/hello', data: 'Hello!' })

tiberiuc/redux-react-firebase
Firebase、React、Redux間の統合

非同期処理

rt2zz/redux-action-buffer
アクションをキューにバッファリングし、解除条件が満たされた時点で一括実行

wyze/redux-debounce
FSA準拠のReduxミドルウェアでアクションをデバウンス

mathieudutour/redux-queue-offline
オフライン時にアクションをキューイングし、オンライン復帰時に実行

分析

rangle/redux-beacon
あらゆる分析サービスと統合可能、オフライン追跡対応、アプリロジックから分析ロジックを分離

markdalgleish/redux-analytics
メタ分析値を持つFlux Standard Actionを監視・処理

エンティティとコレクション

tommikaikkonen/redux-orm
Reduxストア内のリレーショナルデータ管理用シンプルなイミュータブルORM

Versent/redux-crud
CRUDロジック向けの規約ベースアクションとリデューサ

kwelch/entities-reducer
Normalizrのデータを処理する高階リデューサ

amplitude/redux-query
コンポーネントにデータ依存関係を宣言、マウント時にクエリ実行、楽観的更新、Reduxアクションによるサーバー変更トリガー

cantierecreativo/redux-bees
データ正規化を行う宣言的JSON-API連携、クエリ実行可能なReact HOC付属

GetAmbassador/redux-clerk
正規化、楽観的更新、同期/非同期アクションクリエイター、セレクター、拡張可能リデューサを備えた非同期CRUD処理

shoutem/redux-io
非同期CRUD、正規化、楽観的更新、キャッシュ、データステータス、エラー処理を備えたJSON-API抽象化

jmeas/redux-resource
リモートサーバーに永続化される「リソース」管理のための小型かつ強力なシステム

コンポーネント状態とカプセル化

threepointone/redux-react-local
コンポーネントアクション処理を備えたRedux内ローカルコンポーネント状態

@local({
ident: 'counter', initial: 0, reducer : (state, action) => action.me ? state + 1 : state }
})
class Counter extends React.Component {

epeli/lean-redux
setState並みの簡易さでRedux内コンポーネント状態を管理

const DynamicCounters = connectLean(
scope: "dynamicCounters",
getInitialState() => ({counterCount : 1}),
addCounter, removeCounter
)(CounterList);

DataDog/redux-doghouse
コンポーネントインスタンスにスコープ化されたアクションとリデューサで、再利用可能コンポーネントの構築を容易化

const scopeableActions = new ScopedActionFactory(actionCreators)
const actionCreatorsScopedToA = scopeableActions.scope('a')
actionCreatorsScopedToA.foo('bar') //{ type: SET_FOO, value: 'bar', scopeID: 'a' }

const boundScopeableActions = bindScopedActionFactories(
scopeableActions,
store.dispatch
)
const scopedReducers = scopeReducers(reducers)

開発ツール

デバッガーとビューアー

reduxjs/redux-devtools

Dan Abramovによるオリジナル実装。アプリ内状態表示とタイムトラベルデバッグを実現

zalmoxisus/redux-devtools-extension

Mihail Diordievによるブラウザ拡張機能。複数のステートモニタービューを統合し、ブラウザの開発者ツールとの連携を追加

infinitered/reactotron

ReactおよびReact Nativeアプリを検査するクロスプラットフォームElectronアプリ。アプリ状態、APIリクエスト、パフォーマンス、エラー、Saga、アクション発行などを監視可能

DevToolsモニター

Log Monitor
Redux DevToolsのデフォルトモニター。ツリービューで状態を表示

Dock Monitor
Redux DevToolsモニター用のリサイズ可能・移動可能なドック

Slider Monitor
記録されたReduxアクションを再生するカスタムモニター

Diff Monitor
アクション間のReduxストア変更差分を表示するモニター

Filterable Log Monitor
フィルタリング可能なツリービューモニター

Filter Actions
アクションをフィルタリング可能な構成可能モニター

ロギング

evgenyrodionov/redux-logger
アクション・状態・差分を表示するロギングミドルウェア

inakianduaga/redux-state-history
タイムトラベル機能と効率的なアクション記録を提供。アクションログのインポート/エクスポートや再生が可能

joshwcomeau/redux-vcr
ユーザーセッションのリアルタイム記録と再生

socialtables/redux-unhandled-action
状態変更を引き起こさなかったアクションを開発時に警告

変更検出

leoasis/redux-immutable-state-invariant
ディスパッチ中またはディスパッチ間での状態変更を検出するとエラーをスローするミドルウェア

flexport/mutation-sentinel
ランタイムでの深い変更検出を支援し、コードベースの不変性を強制

mmahalwy/redux-pure-connect
react-reduxのconnectに不純なpropsを生成するmapState関数が渡された場合に検出・ログ出力

テスト

arnaudbenard/redux-mock-store
ディスパッチされたアクションを配列に保存してアサーション可能にするモックストア

Workable/redux-test-belt
ストアAPIを拡張し、アサーション・分離・操作を容易化

conorhastings/redux-test-recorder
アプリ内のアクションに基づいて自動的にreducerテストを生成するミドルウェア

wix/redux-testkit
Reduxプロジェクト(リデューサ、セレクタ、アクション、サンク)をテストするための完全でオピニオン化されたテストキット

jfairbank/redux-saga-test-plan
サガの統合テストと単体テストを簡単にする

ルーティング

supasate/connected-react-router React Router v4+の状態をReduxストアと同期

faceyspacey/redux-first-router
シームレスなReduxファーストルーティング。ルートやコンポーネントではなく状態でアプリを考えつつ、アドレスバーを同期。すべてが状態。コンポーネントを接続しFlux標準アクションをディスパッチするだけ

フォーム

erikras/redux-form
React HTMLフォームの状態をReduxに保存するためのフル機能ライブラリ

davidkpiano/react-redux-form
React Redux Formは、複雑なカスタムフォームでもReactとReduxでシンプルかつ高性能に実装できるリデューサクリエイターとアクションクリエイターのコレクション

高レベル抽象化

keajs/kea
Redux、Redux-Saga、Reselectの抽象化レイヤー。アプリのアクション、リデューサ、セレクタ、サガのフレームワークを提供。setStateレベルの簡易さでReduxを強化。ボイラープレートを削減しつつ合成可能性を保持

TheComfyChair/redux-scc
定義済み構造を使用し「ビヘイビア」でアクション・リデューサ応答・セレクタのセットを生成

Bloomca/redux-tiles
Redux上に最小限の抽象化を提供。合成の容易さ、非同期リクエストの簡素化、合理的なテスト可能性を実現

コミュニティ規約

Flux Standard Action
人間に優しいFluxアクションオブジェクト規格

Canonical Reducer Composition
ネストされたリデューサ合成のためのオピニオン化規格

Ducks: Redux Reducer Bundles
リデューサ、アクションタイプ、アクションをバンドルする提案