/web-app-template

Web application template

Primary LanguageTypeScriptMIT LicenseMIT

web-app-template

Web application template web-app-template.deniss-muhla.now.sh


Libraries and technologies


Key concepts

Connector class is heart of modularized redux store. With it's help we can create consistent and refactoring friendly state management system.

src\utils\connector.ts

Steps to add new store module

  1. Create type shape of store and actions
export interface CustomState extends ConnectorState {
    customString: string;
    customObject: {
        prop1: number
    };
}

export type CustomActions = {
    // Simple action without payload
    customAction: ConnectorAction,
    // Simple action with payload
    customPayloadAction: ConnectorPayloadAction<string>,
    // Async action with request and response payloads
    customAsyncPayloadAction: ConnectorAsyncPayloadAction<number, number>
};
  1. Define connector configuration with reducers and redux sagas
// connected react component store state to props mapper
const mapStateToProps = (state: CustomState, _ownProps: {}, globalState: {}) => {
    // Select props from other connector
    const { firstProp } = firstNestedConnector.getState(globalState);
    return {
        ...state,
        firstProp
    };
};

const customCreateConnectorOptions: CreateConnectorOptions<CustomState, CustomActions> = {
    // module name
    name: 'app',
    // initial module state
    initialState: {
        customString: '',
        customObject: {
            prop1: 0
        }
    },
    // reducers
    actionReducers: {
        customAction: state => {
            state.customString = 'a';
            state.customObject.prop1 = 1;
        },
        customPayloadAction: (state, action) => {
            state.customString = action.payload;
        },
        customAsyncPayloadAction: {
            request: (state, action) => {
                state.customString = `Start update ${action.payload}`;
            },
            response: (state, action) => {
                state.customObject.prop1 = action.payload;
            }
        }
    },
    // redux sagas for business logic
    actionSagas: {
        // async method as example fetch data from API
        customAsyncPayloadAction: async function(_connector, requestPayload) {
            return Promise.resolve(requestPayload + 1);
        }
    },
    // child connector modules
    nestedConnectors: [firstNestedConnector, secondNestedConnector],
    // use component props mapper
    mapStateToProps
};
  1. Create connector class instance and export
// Create new connector
const customConnector = new Connector<CustomState, CustomActions>(customCreateConnectorOptions);

// Define component props type
export type CustomProps = ConnectorProps<ReturnType<typeof mapStateToProps>, CustomActions>;
export { customConnector };

Project scripts

start development server

yarn start

run tests

yarn cypress:open

build production distributive

yarn build