Redux는 JavaScript의 Redux를 영감으로 하여 Dart 및 Flutter 애플리케이션을 위한 예측 가능한 상태 관리 솔루션입니다. 순수한 리듀서 함수를 통해 일관된 업데이트를 보장하는 중앙 저장소를 제공합니다. 미들웨어 지원과 개발자 도구 통합을 통해 디버깅 및 타임트래블 기능을 가능하게 합니다. 확장성을 고려하여 설계되어 여러 컴포넌트 간 구조화된 상태 처리가 필요한 중대형 앱에 적합합니다.
사용 사례
복잡한 앱 상태 관리
시간 여행 디버깅 활성화
대규모 플러터 애플리케이션 지원
사이드 이펙트를 위한 미들웨어 통합
상태 로직에서 팀 협업을 촉진하기
주요 기능
중앙 집중형 상태 저장소
불변 상태 업데이트
미들웨어 지원
DevTools 통합
예측 가능한 상태 전이
적합한 대상
대규모 플러터 프로젝트
구조화된 상태 관리가 필요한 팀
디버깅 기능이 필요한 앱
Redux 패턴에 익숙한 개발자
복잡한 데이터 흐름을 가진 프로젝트
고려 사항
초보자를 위한 학습 곡선이 더 가파릅니다
필요한 보일러플레이트 코드
간단한 앱에 과도함
상태 설계에 신중이 필요합니다
제한된 내장 비동기 처리
원본 README
연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.
Redux for Dart using generics for typed State. It includes a rich ecosystem of Docs, Middleware, Dev Tools and can be combined with Flutter using the flutter_redux package.
Docs
Motivation and Principles - Learn why Redux might make sense for your app and the principles behind it.
Basics - Introduction to the core concepts in Redux
Combining Reducers - combineReducers works a bit differently in Dart than it does in JS. Learn why, and how to combine reducers in a type-safe way!
Async with Middleware - Learn how to make async calls, such as to a web service or local database, with Redux.
inKino App - A cross platform movie and showtime browser for Finnkino cinemas built with Redux. Lots of testing included as well!
flutter_architecture_samples - A Todo List App with local storage and multiple screens. Includes a README describing how to combine Redux with Flutter effectively.
redux_logging - Connects a Logger to a Store, and can print out actions as they're dispatched to your console.
redux_thunk - Allows you to dispatch functions that perform async work as actions.
redux_future - For handling Dart Futures that are dispatched as Actions.
redux_epics - Middleware that allows you to work with Dart Streams of Actions to perform async work.
Dev Tools
The redux_dev_tools library allows you to create a DevToolsStore during dev mode in place of a normal Redux Store.
This DevToolsStore will act exactly like a normal Store at first. However, it will also allow you to travel back and forth throughout the States of your app or recompute the State of your app by replaying all actions through your reducers. This works perfectly with Hot Reloading!
You can combine the DevToolsStore with your own UI to travel in time, or use one of the existing options for the platform you're working with:
reselect - Efficiently derive data from your Redux Store with memoized functions.
redux_persist - Persist Redux State, works for Web and Flutter
Usage
import'package:redux/redux.dart';
// Create typed actions. You will dispatch these in order to// update the state of your application.enumActions {
increment,
decrement,
}
// Create a Reducer. A reducer is a pure function that takes the // current State (int) and the Action that was dispatched. It should// combine the two into a new state without mutating the state passed// in! After the state is updated, the store will emit the update to // the `onChange` stream.// // Because reducers are pure functions, they should not perform any // side-effects, such as making an HTTP request or logging messages// to a console. For that, use Middleware.intcounterReducer(int state, action) {
if (action == Actions.increment) {
return state + 1;
} elseif (action == Actions.decrement) {
return state - 1;
}
return state;
}
// A piece of middleware that will log all actions with a timestamp// to your console!// // Note, this is just an example of how to write your own Middleware.// See the redux_logging package on pub for a pre-built logging // middleware.loggingMiddleware(Store<int> store, action, NextDispatcher next) {
print('${new DateTime.now()}: $action');
next(action);
}
main() {
// Create the store with our Reducer and Middlewarefinal store = newStore<int>(
counterReducer,
initialState: 0,
middleware: [loggingMiddleware],
);
// Render our State right awayrender(store.state);
// Listen to store changes, and re-render when the state is updated
store.onChange.listen(render);
// Attach a click handler to a button. When clicked, the `INCREMENT` action// will be dispatched. It will then run through the reducer, updating the // state.//// After the state changes, the html will be re-rendered by our `onChange`// listener above. querySelector('#increment').onClick.listen((_) {
store.dispatch(Actions.increment);
});
}
render(int state) {
querySelector('#value').innerHtml = '${state}';
}