With scene, you can just be lazy
- actions are likely to be completely shared among all members under same scenes
- selector is meaningless individually, yet the use of reselect can produce stateProps directly
- actions are overwhelming reused since mapping of unused actions results in insignificant overhead only
- selectors are selectively combined to stateProps function that used by container
- containers are just composed by connect, translate, and other enhancers
Design principle: SDK
// ./common/actions/ProfileViewer.js
import { SHOW_CLUB_DETAIL, SHOW_REPORT_DETAIL } from './constants.js';
export const navigateToClub = (params) => ({
type: SHOW_CLUB_DETAIL,
...params
})
export const navigateToReport = ({profile_id}) => ({
type: SHOW_REPORT_DETAIL,
profile_id
})
// ./common/stateProps/ProfileViewer.js
const profiles = (state) => state.models.Profiles;
const current_profile_id = (state) => state.ProfileViewer.current_id;
const clubs = (state) => state.models.Clubs;
const current_profile = createSelector(
current_profile_id,
profiles,
(current_profile_id, profiles) => profiles[current_profile_id]
)
/* actually this is mapStateToProps */
export const TeacherProfileProps = (state) => {
current_profile: current_profile(state)
}
/* {
current_profile: { profile_id, gender }
} */
/* actually this is mapStateToProps */
export const StudentProfileProps = createSelector(
current_profile,
clubs,
(current_profile, clubs) => {
let _clubs = _.chain(current_profile.clubs).map({id} => clubs[is]).value();
return { current_profile, _clubs }
}
)
/* {
current_profile: {
profile_id,
gender,
clubs: [ids]
} ,
_clubs: [
{ id, member_count }
]
} */
// ./common/containers/ProfileViewer.js
import * as actions from '../actions/ProfileViewer.js'; // {navigateToClub: f, navigateToReport: f}
import { TeacherProfileProps, StudentProfileProps } from '../stateProps/ProfileViewer.js';
export const _TeacherProfile = compose(
connect(TeacherProfileProps, actions), translate('Profile'));
export const _StudentProfile = compose(
connect(StudentProfileProps, actions), translate('Profile'));
// ./common/containers/index.js
export * from './ProfileViewer.js'
// ./common/index.js
export * from './containers';
// ./app/scenes/ProfileViewer/TeacherProfile.js
import { _TeacherProfile } from 'sdk';
const Presenter = ({current_profile}) => {
}
export _TeacherProfile(Presenter);
// ./app/scenes/ProfileViewer/StudentProfile.js
import { _StudentProfile } from 'sdk';
const Presenter = ({current_profile, _clubs, navigateToClub, navigateToReport}) => {
}
export _StudentProfile(Presenter);
// Add babel-plugin-module-alias to ~/package.json
"babel":{
"plugins": [[
"module-alias", [
{ "src": "./common/containers", "expose": "sdk" },
{ "src": "./common/sagas", "expose": "sdk/saga"},
{ "src": "./common/reducers", "expose": "sdk/reducer"}
]
]]
}