Upgrade to Pro — share decks privately, control downloads, hide ads and more …

frontend_validation.pdf

ktp
September 04, 2019

 frontend_validation.pdf

ktp

September 04, 2019
Tweet

More Decks by ktp

Other Decks in Programming

Transcript

  1. Motivation • Fat component/container ͷճආ • ಠཱͨ͠ػߏͰ࣮૷ ≒ ੹຿ͷ෼཭ •

    ֎෦ϥΠϒϥϦ΁ͷґଘճආ • Ұͭͷػߏʹ validation Λू໿
  2. ΤϥʔϝοηʔδͷܕΛఆٛ # src/reducers/errors.tsx + type ValidateStates = "email"; + type

    ErrorMessage = string; + type Errors = { [key in ValidateStates]?: ErrorMessage }
  3. actionΛఆٛ # src/actions/actions.tsx + export const validationSuccess = (key: ValidateStates)

    => ({ + type: AppActionTypes.VALIDATION_SUCCESS as const, + key + }); + export const validationFailure = (errors: Errors) => ({ + type: AppActionTypes.VALIDATION_FAILURE as const, + errors + });
  4. reducerΛఆٛ # src/reducers/errors.tsx export const errors = (state = initialErrors,

    action: AppAction): Errors => { switch (action.type) { + case AppActionTypes.VALIDATION_FAILURE: // ࣦഊ࣌ + return { + ...state, + ...action.errors + }; + case AppActionTypes.VALIDATION_SUCCESS: // ੒ޭ࣌ + const nextState = { ...state }; + delete nextState[action.key]; + return nextState; default: return state; }
  5. What is middleware? • redux ͷ dispatch Λ֦ு͢Δػߏ • ϐϡΞͳ

    dispatch ͸ϓϨʔϯͳΦϒδΣΫτ͔͠ड͚ औΕͳ͍ • Ex redux-thunk
  6. Ex. redux-thunk ແ͠ // action ͸ϓϨʔϯͳΦϒδΣΫτΛฦ͢ const increment = ()

    => { return { type: INCREMENT_COUNTER, }; } // dispatch ͸ϓϨʔϯͳΦϒδΣΫτͷΈड͚औΕΔ dispatch(increment())
  7. Ex. redux-thunk ༗Γ // function Λฦ͢ action Λఆٛ const incrementAsync

    = () => { return (dispatch) => { setTimeout(() => { // Yay! Can invoke sync or async actions with `dispatch` dispatch(increment()); // ͦͷதͰ͞Βʹ action Λ dispatch }, 1000); }; } // dispatch ͸ function ΋ड͚औΕΔ dispatch(incrementAsync())
  8. middlewareͷܕ # src/node_modules/redux/index.d.ts export interface Middleware< DispatchExt = {}, S

    = any, D extends Dispatch = Dispatch > { (api: MiddlewareAPI<D, S>): ( next: Dispatch<AnyAction> ) => (action: any) => any } => ؔ਺Λฦؔ͢਺Λฦؔ͢਺ => ܹ͍͠ΧϦʔԽ
  9. middlewareͷجຊܗ const validator = ({ dispatch, getState }) => next

    => action => { // ͜͜ʹ൑ఆϩδοΫͱɺaction dispatch Λ࣮૷ // ࣍ͷ middleware ·ͨ͸ store ͷ dispatch ͕ݺͼग़͞ΕΔ return next(action); };
  10. middlewareͷجຊܗ (ܕ༗Γ) + const validator = ({ dispatch, getState }:

    MiddlewareAPI<AppThunkDispatch>) => ( + next: Dispatch + ) => (action: AppAction) => { + return next(action); + }; + + export default validator;
  11. middlewareͷ࣮૷ const validator = ({ dispatch, getState }: MiddlewareAPI<AppThunkDispatch>) =>

    ( next: Dispatch ) => (action: AppAction) => { + switch (action.type) { + case AppActionTypes.UPDATE_EMAIL: // dispatchʹόϦσʔγϣϯؔ਺Λ౉͢ʢredux-thunk Λ࢖༻ʣ + dispatch(validateEmail(action.email)); + break; + default: + break; } return next(action); }; export default validator;
  12. όϦσʔγϣϯؔ਺ (thunk actin) + const validateEmail = (email: string): AppThunkAction<void>

    => dispatch => { + let errorMessage: string = ""; // validator Λ࢖ͬͯඞਢνΣοΫ + if (isEmpty(email)) { + errorMessage = "Email is required."; + } + if (errorMessage === "") { + dispatch(validationSuccess(“email")); // ੒ޭ࣌ + } else { + dispatch(validationFailure({ email: errorMessage })); // ࣦഊ࣌ + } + };
  13. # src/index.tsx + import thunk from “redux-thunk"; + import validator

    from "./middleware/validator"; - const store = createStore(reducer) + const store = createStore(reducer, applyMiddleware(thunk, validator)); applyMiddleware
  14. # src/containers/AppContainer.tsx + const mapStateToProps = (state: AppState) => ({

    + errors: state.errors + }); # src/components/App.tsx + const App: React.FC<AppProps> = ({ errors, onChangeEmail }) => { ~~ + <p>{errors.email}</p> display errors
  15. Pros • Fat component/container ͷճආ • ಠཱͨ͠ػߏͰ࣮૷ ≒ ੹຿ͷ෼཭ •

    ֎෦ϥΠϒϥϦ΁ͷґଘճආ • Ұͭͷػߏʹ validation Λू໿