A starter project using Redux state management.
Path | Description | |
---|---|---|
lib/main.dart |
Main entry file. | |
lib/app.dart |
App declarations and entry file. | |
lib/locator.dart |
Dependency set-up. | |
lib/app_state.dart |
App state model. | |
lib/app_router.dart |
App page routing. | |
lib/features/* |
App features. | 🔗 |
lib/ui/* |
Shared UI. | 🔗 |
assets/* |
Assets directory. | |
android/* |
Android platform assets. | |
ios/* |
iOS platform assets. | |
web/* |
Web platform assets. | |
test/* |
Tests. |
Shared UI concerns and declarations. Shared UI libraries are located at libs/ui
.
Path | Description | |
---|---|---|
layouts/* |
Shared layout widgets | 🔗 |
theme/* |
Theme declarations | 🔗 |
widgets/* |
Shared widgets | 🔗 |
TODO
Path | Description |
---|---|
theme/colors.dart |
Theme color declarations. |
theme/text.dart |
Theme text style declarations. |
theme/theme.dart |
Theme data. |
TODO
All features are kept in the lib/features
directory.
Path | Description | |
---|---|---|
{feature}/{feature}_router.dart |
Feature page routing, if required. | 🔗 |
{feature}/pages/* |
Pages for this feature, if any. | 🔗 |
{feature}/services/* |
Services for this feature, if any. | |
{feature}/+state/* |
Supplementary state for this feature, if required. | 🔗 |
If page routing is required, the feature directory will need a router.
Feature routers are of type Map<String, Widget Function(BuildContext)>
, mapping routes to widget builders. All routes should be prefixed with '/'
, eg. /home
.
Path | Description |
---|---|
{feature}_router.dart |
Naming scheme for a feature router. |
Feature pages are located at lib/features/{feature}/pages
.
Path | Description |
---|---|
{name}_page.dart |
Naming scheme for feature pages. |
All state related logic for a feature is located at lib/features/{feature}/+state
.
Path | Description |
---|---|
actions.dart |
Store dispatched actions declarations. |
effects.dart |
Store side-effect declarations. |
facade.dart |
Store facade declaration. |
model.dart |
Store state models for this feature. |
reducer.dart |
Store reducer declarations. |
TODO
TODO
TODO
TODO
TODO
The following assumes a feature named
MyFeature
.
-
Add the feature state key
mixin
to the app state inlib/app_state.dart
. -
Add the state to the
AppState
constructor as a requirement. -
Add the initial state to the initial app state in the
AppState.initial()
factory. -
Ensure the
copyWith
function accommodates for the new feature state. -
Include the new feature state in
hashCode
generation. -
Include the new feature state in the object equality override.
/// Add feature state key mixin to app state.
class AppState with MyFeatureStateKey {
/// Declare the feature state property.
final MyFeatureState myFeatureState;
final bool isLoading;
AppState({
/// Include requirement in constructor.
@required this.myFeatureState,
this.isLoading
});
/// Include in state copy method
AppState copyWith({MyFeatureState myFeatureState, bool isLoading}) {
return AppState(
myFeatureState: myFeatureState ?? this.myFeatureState,
isLoading: isLoading ?? this.isLoading);
}
/// Include is hashCode
@override
int get hashCode =>
isLoading.hashCode ^ myFeatureState.hashCode;
/// Include in equality comparison
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is AppState && myFeatureState == other.myFeatureState;
}
The following assumes an app named
MyApp
and a feature namedMyFeature
.
-
Import the feature router into
app.dart
. -
In the app constructor, call
registerRouter([router])
to register the feature router.
/// Feature import.
import 'features/my_feature/my_feature_router.dart';
/// Ensure app router is imported.
import 'app_router.dart';
class MyApp {
MyApp(){
registerRouter(myFeatureRouter);
/// Other routers...
}
/// etc.
}