본문으로 건너뛰기
비공식 베타 번역

이 페이지는 PageTurner AI로 번역되었습니다(베타). 프로젝트 공식 승인을 받지 않았습니다. 오류를 발견하셨나요? 문제 신고 →

생태계

Redux는 작은 라이브러리지만, 그 계약과 API는 도구와 확장 기능의 생태계를 만들도록 신중하게 설계되었습니다. 커뮤니티는 다양한 유용한 애드온, 라이브러리, 도구를 만들어 왔습니다. Redux를 사용하기 위해 이러한 애드온을 반드시 사용할 필요는 없지만, 기능 구현과 문제 해결을 더 쉽게 만들어 줄 수 있습니다.

Redux 관련 라이브러리, 애드온, 도구의 광범위한 목록은 Redux Ecosystem Links 목록을 참조하세요. 또한 React/Redux Links 목록에는 React나 Redux를 배우는 사람들을 위한 튜토리얼과 유용한 자료가 포함되어 있습니다.

이 페이지는 Redux 관리자가 직접 검증했거나 커뮤니티에서 널리 채택된 Redux 관련 애드온을 소개합니다. 나머지 항목도 꼭 시도해 보세요! 생태계는 너무 빠르게 성장해서 모든 것을 살펴볼 시간이 제한적입니다. 이 목록을 '스태프 추천'으로 생각하고, Redux로 멋진 것을 만들었다면 주저하지 말고 PR을 제출해 주세요.

목차

라이브러리 통합 및 바인딩

reduxjs/react-redux
Redux 팀이 유지 관리하는 공식 React 바인딩

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
리듀서를 위한 손쉬운 실행 취소/다시 실행 및 액션 기록

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
오프라인 우선(Offline-First) 앱을 위한 영속적 저장소로 낙관적 UI(optimistic UI) 지원

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

불변 데이터(Immutable Data)

ImmerJS/immer
프록시(Proxies)를 사용해 일반적인 변형 코드로 불변 업데이트 구현

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

부수 효과(Side Effects)

널리 사용되는 도구(Widely Used)

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는 효과(effect)에 대한 설명을 반환하며, 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 관찰 가능 체인(observable chains)으로 비동기 로직 처리. 부수 효과 생성 등을 위해 비동기 액션 구성 및 취소

최적 사용처: 복잡한 비동기 로직, 분리된 워크플로

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

관찰 가능체(observables) 기반 부수 효과 라이브러리로, 콜백/프로미스/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)
}
})

프로미스(Promises)

acdlite/redux-promise
프로미스를 액션 페이로드로 디스패치하며, 프로미스가 이행(resolve)되거나 거부(reject)될 때 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의 전체 기능을 노출하지 않으면서도 사용자를 올바른 방향으로 이끄는 합리적이고 선언적인 관례 기반 프로미스 처리

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 }),
});

미들웨어(Middleware)

네트워크 및 소켓(Networks and Sockets)

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 표준 액션을 감지하고 처리

엔티티와 컬렉션

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
Redux에서 setState만큼 쉬운 컴포넌트 상태 관리

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의 원본 Redux DevTools 구현체, 앱 내 상태 표시 및 시간 여행 디버깅 지원

zalmoxisus/redux-devtools-extension

Mihail Diordiev의 브라우저 확장 프로그램으로, 여러 상태 모니터 뷰를 번들로 제공하며 브라우저 자체 개발 도구와의 통합 기능을 추가합니다.

infinitered/reactotron

크로스 플랫폼 Electron 애플리케이션으로 React 및 React Native 앱을 검사할 수 있으며, 앱 상태, API 요청, 성능, 오류, 사가(sagas), 액션 디스패칭 등을 포함합니다.

DevTools 모니터

Log Monitor
트리 뷰를 제공하는 Redux DevTools의 기본 모니터

Dock Monitor
Redux DevTools 모니터를 위한 크기 조절 및 이동이 가능한 독(Dock)

Slider Monitor
기록된 Redux 액션을 재생하기 위한 Redux DevTools 커스텀 모니터

Diff Monitor
액션 간 Redux 스토어 변이(mutation) 차이를 보여주는 Redux DevTools 모니터

Filterable Log Monitor
필터링 가능한 트리 뷰 모니터 for Redux DevTools

Filter Actions
액션 필터링 기능을 가진 Redux DevTools 구성 가능 모니터

로깅

evgenyrodionov/redux-logger
액션, 상태 및 상태 차이를 보여주는 로깅 미들웨어

inakianduaga/redux-state-history
시간 여행 및 효율적인 액션 기록 기능을 제공하는 강화기(enhancer), 액션 로그 임포트/익스포트 및 액션 재생 기능 포함

joshwcomeau/redux-vcr
실시간으로 사용자 세션 기록 및 재생

socialtables/redux-unhandled-action
개발 환경에서 상태 변경을 발생시키지 않은 액션에 대해 경고

변이 감지

leoasis/redux-immutable-state-invariant
디스패치 중 또는 디스패치 간 상태 변이를 시도할 때 오류를 발생시키는 미들웨어

flexport/mutation-sentinel
런타임에 깊은 수준의 변이를 감지하고 코드베이스의 불변성(immutability)을 강제하는 도구

mmahalwy/redux-pure-connect
react-redux의 connect 메서드에 불순한 props를 생성하는 mapState 함수가 전달되는지 확인하고 기록

테스팅

arnaudbenard/redux-mock-store
디스패치된 액션을 어설션(assertion)을 위해 배열에 저장하는 모의(mock) 스토어

Workable/redux-test-belt
스토어 API를 확장하여 어설션, 격리 및 조작을 더 쉽게 만드는 도구

conorhastings/redux-test-recorder
앱 내 액션을 기반으로 리듀서 테스트를 자동 생성하는 미들웨어

wix/redux-testkit
Redux 프로젝트(리듀서, 셀렉터, 액션, thunk) 테스트를 위한 완전하고 독립적인 구조의 테스트킷

jfairbank/redux-saga-test-plan
saga의 통합 및 단위 테스트를 매우 쉽게 만들어주는 도구

라우팅

supasate/connected-react-router React Router v4+ 상태를 Redux 스토어와 동기화

faceyspacey/redux-first-router
매끄러운 Redux-우선 라우팅. 앱을 라우트나 컴포넌트가 아닌 상태(state)로 생각하며 주소창을 동기화. 모든 것은 상태입니다. 컴포넌트를 연결하고 flux 표준 액션을 디스패치하기만 하면 됩니다.

erikras/redux-form
React HTML 폼 상태를 Redux에 저장할 수 있게 하는 모든 기능을 갖춘 라이브러리

davidkpiano/react-redux-form
리듀서 생성자와 액션 생성자의 모음으로, React와 Redux로 복잡한 커스텀 폼을 간단하고 성능 좋게 구현

고수준 추상화

keajs/kea
Redux, Redux-Saga, Reselect를 추상화한 도구. 앱의 액션/리듀서/셀렉터/saga를 위한 프레임워크 제공. setState만큼 간편하게 사용 가능. 구성성 유지하며 상용구 감소

TheComfyChair/redux-scc
정의된 구조와 'behaviors'를 사용해 액션/리듀서 응답/셀렉터 세트 생성

Bloomca/redux-tiles
Redux 위에 최소한의 추상화 계층을 제공해 쉬운 구성성, 비동기 요청, 테스트 가능성 확보

커뮤니티 규약

Flux Standard Action
Flux 액션 객체를 위한 인간 친화적 표준

Canonical Reducer Composition
중첩 리듀서 구성을 위한 독립적인 표준

Ducks: Redux Reducer Bundles
리듀서/액션 타입/액션을 번들링하는 제안