redux-actions-promise-wrapper
TypeScript icon, indicating that this package has built-in type declarations

1.1.0 • Public • Published

Build Status Coverage Status

redux-actions-promise-wrapper

Type safe redux action creator (works with redux saga)

Installation

npm install redux-actions-promise-wrapper --save
yarn add redux-actions-promise-wrapper
bower install redux-actions-promise-wrapper --save

Feature

Create type safe action creators and enable callback for redux saga.

Example Project

https://github.com/thu-san/redux-actions-promise-wrapper-usage-example

Usage

TypeScript

Create Action
import { createAction } from 'redux-actions-promise-wrapper';
 
const login = createAction('LOGIN/TRIGGER', 'LOGIN/SUCCESS', 'LOGIN/FAILURE')<
  {
    emailstring;
    passwordstring;
  },
  {
    sessionstring;
  }
>();

login now contains the following properties

login.TRIGGER = 'LOGIN/TRIGGER';
login.SUCCESS = 'LOGIN/SUCCESS';
login.FAILURE = 'LOGIN/FAILURE';
 
login.trigger(payload) === { type: 'LOGIN/TRIGGER', payload }; // payload must have type { email: string, password: string }
login.success(payload) === { type: 'LOGIN/SUCCESS', payload }; // payload must have type { session: string }
login.failure() ===  { type: 'LOGIN/FAILURE' };
 
login(payload) === login.trigger(payload);
You can also call on login for trigger action.

Redux Saga Example

Types, Saga and Reducer
// TYPES
interface ILoginTriggerPayload {
  account: string;
}
 
export const loginAction = createAction('LOGIN/TRIGGER', 'LOGIN/SUCCESS')(
  handleLogin,
  function*(arg: { session: string; account: string }) {
    return undefined;
  }
);
export const logoutAction = createAction('LOGOUT/TRIGGER')<{
  session: string;
}>();
 
// SAGA
function* handleLogin({ account }: ILoginTriggerPayload) {
  yield delay(1000);
  const putLoginSuccess = put(
    loginAction.success({ session: new Date().toString(), account })
  );
  yield putLoginSuccess;
  return reg(account);
}
 
export function* authSaga() {
  yield all([takeLatest(loginAction.TRIGGER, loginAction.handleTrigger)]);
}
 
// REDUCER
interface IAuth {
  account?: string;
  session?: string;
}
 
const INITIAL_STATE: IAuth = {};
 
type Actions = ExtractActions<{
  loginAction: typeof loginAction;
  logoutAction: typeof logoutAction;
}>;
 
const reducer: Reducer<IAuth, Actions> = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case loginAction.SUCCESS: {
      const { account, session } = action.payload;
      return { ...state, account, session };
    }
    case logoutAction.TRIGGER: {
      const { session } = action.payload;
      console.log(`LOGOUT Reducer Session -  ${session}`);
      return {};
    }
    default:
      return state;
  }
};
 
export default reducer;
Combine Reducer
import { combineReducers } from 'redux';
import { all } from 'redux-saga/effects';
 
import auth, { authSaga } from './auth';
 
const reducers = combineReducers({
  auth 
});
 
export type AppState = ReturnType<typeof reducers>;
 
// saga
export const rootSaga = function*() {
  yield all([authSaga()]);
};
 
export default reducers;
Container
interface IState {
  account: string;
  loading: boolean;
}
type IProp = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps;
export class Dash extends PureComponent<IProp, IState> {
  state: IState = {
    account: '',
    loading: false
  };
 
  handleLogin = async () => {
    const { loginAction } = this.props;
    const { account } = this.state;
    this.setState({ loading: true });
    const { promise } = loginAction({ account });
    const result = await promise;
    alert(`You are now logged in as ${result}`);
    this.setState({ loading: false });
  };
 
  handleLogout = async () => {
    const { session, logoutAction } = this.props;
    if (session) {
      logoutAction({ session });
    }
  };
 
  render() {
    const { session, account: authAccount } = this.props;
    const { account, loading } = this.state;
 
    const loggedIn = !!session;
 
    return (
      <div
        style={{
          display: 'flex',
          height: 500,
          background: 'cyan',
          justifyContent: 'center',
          alignItems: 'center'
        }}
      >
        <div>
          <p>Status{loggedIn ? 'Logged In' : 'Logged Out'}</p>
          <p>Session{session}</p>
          <p>Email{authAccount}</p>
          {loading ? (
            '...loading'
          ) : loggedIn ? (
            <button onClick={this.handleLogout}>Logout</button>
          ) : (
            <>
              <p>
                <input
                  type="text"
                  placeholder="account"
                  value={account}
                  onChange={({ target: { value } }) =>
                    this.setState({ account: value })
                  }
                />
              </p>
              <button onClick={this.handleLogin}>Login</button>
            </>
          )}
        </div>
      </div>
    );
  }
}
 
const mapStateToProps = ({ auth: { account, session } }: AppState) => ({
  account,
  session 
});
 
const mapDispatchToProps = {
  loginAction,
  logoutAction 
};
 
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Dash);

Dependents (0)

Package Sidebar

Install

npm i redux-actions-promise-wrapper

Weekly Downloads

6

Version

1.1.0

License

MIT

Unpacked Size

573 kB

Total Files

45

Last publish

Collaborators

  • thu-san