Skip to content

Instantly share code, notes, and snippets.

@geakstr
Created January 9, 2019 20:36
Show Gist options
  • Save geakstr/b780a10ebc2c4496e517d754881e887c to your computer and use it in GitHub Desktop.
Save geakstr/b780a10ebc2c4496e517d754881e887c to your computer and use it in GitHub Desktop.
Snippet for safenv lib
// ./utils
import { createInject, createReducerCreator } from "safenv";
import { actions } from "~/state/actions";
import { selectors } from "~/state/selectors";
import { store } from "~/state/store";
export const inject = createInject({
store,
actions,
selectors,
extras: {}
});
export const createReducer = createReducerCreator({
actions
});
// ./state/reducer.ts
import { combineReducers, Store } from "redux";
import {
reducer as authReducer,
State as AuthState
} from "~/modules/auth/state/reducer";
import { RootAction } from "./actions";
export const rootReducer = combineReducers<RootState, RootAction>({
auth: authReducer,
});
export interface RootState {
readonly auth: AuthState;
}
export type RootStore = Store<RootState, RootAction>;
// ./state/actions.ts
import { ActionType } from "safenv";
import * as auth from "~/modules/auth/state/actions";
export const actions = {
auth
};
export type Actions = typeof actions;
export type RootAction = ActionType<Actions>;
// ./state/selectors.ts
import * as auth from "~/modules/auth/state/selectors";
export const selectors = {
auth
};
export type Selectors = typeof selectors;
// ./modules/auth/state/reducer.ts
import { createReducer } from "~/utils";
export interface State {
accessToken: string | null;
}
const initialState: State = {
accessToken: null,
};
export const reducer = createReducer(
({ actions, getType }) => (draft, action) => {
switch (action.type) {
case getType(actions.auth.logout): {
return {
accessToken: null,
};
}
case getType(actions.auth.login): {
draft.accessToken = action.payload.accessToken;
break;
}
}
},
initialState
);
// ./modules/auth/state/actions.ts
import { createRequestAction, createStandardAction } from "safenv";
export const login = createStandardAction("Login")<{
readonly accessToken: string;
}>();
export const logout = createStandardAction("Logout")<void>();
// ./modules/auth/state/selectors.ts
import { createSelector } from "reselect";
import { RootState } from "~/state/reducer";
export const getAccessToken = (state: RootState) => state.auth.accessToken;
export const isLoggedIn = createSelector(
getAccessToken,
accessToken => Boolean(accessToken)
);
// ./component.tsx
export const App = inject(({ actions, selectors }) => ({
mapState: state => ({
loggedIn: selectors.auth.isLoggedIn(state)
}),
mapActions: {
login: actions.auth.login,
logout: actions.auth.logout
}
}))(props => {
return (
<>
{props.loggedIn ? <PrivateArea /> : <PublicArea />}
</>
);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment