Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
frontend_validation.pdf
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
ktp
September 04, 2019
Programming
1.8k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
frontend_validation.pdf
ktp
September 04, 2019
More Decks by ktp
See All by ktp
個人プロダクトのはなし@社内LT会
kato1628
1
220
Other Decks in Programming
See All in Programming
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
160
FreeBSDでZabbixを動かす
kenkino
0
330
一人だけ、Kiroが静止する日
hideg
0
130
すこし踏み込む CancellationToken
htkym
2
1.1k
Webの地図
yosuke_furukawa
PRO
6
4.8k
ゲームコントローラやキーボードのファームウェアをSwiftで書く
kishikawakatsumi
1
260
Heart of Swift Concurrency
koher
0
980
Ghostty + Neovimで作る 透明でカッコ良い開発環境
j341nono
0
130
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
2.4k
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
320
WebRTC映像をAirPlayに対応させる挑戦.pdf
monolithic_adam
0
300
SONY CISC-NEWS NWS-1750 + NWB-225 フレームバッファの NetBSD/news68k ドライバ実装 / OSC2026Hiroshima
tsutsui
0
150
Featured
See All Featured
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
It's Worth the Effort
3n
188
29k
First, design no harm
axbom
PRO
2
1.3k
What's in a price? How to price your products and services
michaelherold
247
13k
sira's awesome portfolio website redesign presentation
elsirapls
0
420
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
2
2.9k
A Modern Web Designer's Workflow
chriscoyier
699
190k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
440
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
320
Deep Space Network (abreviated)
tonyrice
0
320
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Transcript
Redux middleware Ͱ ϑϩϯτΤϯυόϦσʔγϣϯ Λ࣮͢Δ @kato1628
@kato1628 ɾReact, Redux, TypeScript ɾSudachi ɾSwimming
Demo
redux flow
redux flow ʮͲ͏มߋ͞ΕΔ͔ʯˡ ʮͲ͏ৼΔ͏͔ʯˡ ʮͲ͏ݟ͑Δ͔ʯˡ
ͲͷϨΠϠʔԚͨ͘͠ͳ͍
redux flow (with validation middleware) ಛఆͷBDUJPO͕EJTQBUDI͞Εͨ߹ʹͷΈɺ WBMJEBUJPOΛ࣮ߦ͢Δɻ FSSPSTUBUF
Motivation • Fat component/container ͷճආ • ಠཱͨ͠ػߏͰ࣮ ≒ ͷ •
֎෦ϥΠϒϥϦͷґଘճආ • Ұͭͷػߏʹ validation Λू
state ͷఆٛ // ͜ΜͳΤϥʔϝοηʔδΛ state ʹ͍࣋ͪͨ errors = { email:
"Email is required" … }
ΤϥʔϝοηʔδͷܕΛఆٛ # src/reducers/errors.tsx + type ValidateStates = "email"; + type
ErrorMessage = string; + type Errors = { [key in ValidateStates]?: ErrorMessage }
actionΛఆٛ
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 + });
reducerΛఆٛ
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; }
✓ state (ͲΜͳ͔) ✓ action (Կ͕ى͜Δ͔) ✓ reducer (Ͳ͏มߋ͞ΕΔ͔) ☐
validation middleware (Ͳ͏ఆ͢Δ͔)
validation middleware ͷ ☑ ఆϩδοΫ => ඞਢνΣοΫɺܻνΣοΫɺ֯ࣈνΣοΫ…etc ☑ ఆ݁Ռͷө =>
action ͷ dispatch
ఆϩδοΫ
validator • จࣈྻόϦσʔγϣϯ • ๛ͳόϦσʔγϣϯϝιου https://github.com/validatorjs/validator.js $ yarn add validator
@types/validator # Example var validator = require('validator'); validator.isEmail('
[email protected]
'); //=> true
middlewareͷ࣮
What is middleware? • redux ͷ dispatch Λ֦ு͢Δػߏ • ϐϡΞͳ
dispatch ϓϨʔϯͳΦϒδΣΫτ͔͠ड͚ औΕͳ͍ • Ex redux-thunk
dispatch ʮSFEVDFSʹBDUJPOΛͯ͠TUBUFΛߋ৽͢Δʯˡ
Ex. redux-thunk ແ͠ // action ϓϨʔϯͳΦϒδΣΫτΛฦ͢ const increment = ()
=> { return { type: INCREMENT_COUNTER, }; } // dispatch ϓϨʔϯͳΦϒδΣΫτͷΈड͚औΕΔ dispatch(increment())
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())
middlewareͷܕ
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 } => ؔΛฦؔ͢Λฦؔ͢ => ܹ͍͠ΧϦʔԽ
ͪΐͬͱ ԿݴͬͯΔ͔Θ͔Βͳ͍
middlewareͷجຊܗ const validator = ({ dispatch, getState }) => next
=> action => { // ͜͜ʹఆϩδοΫͱɺaction dispatch Λ࣮ // ࣍ͷ middleware ·ͨ store ͷ dispatch ͕ݺͼग़͞ΕΔ return next(action); };
middlewareͷجຊܗ (ܕ༗Γ) + const validator = ({ dispatch, getState }:
MiddlewareAPI<AppThunkDispatch>) => ( + next: Dispatch + ) => (action: AppAction) => { + return next(action); + }; + + export default validator;
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;
όϦσʔγϣϯؔ (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 })); // ࣦഊ࣌ + } + };
validation middleware • ఆϩδοΫΛ࣮ߦ • ޭɾࣦഊͦΕͧΕͷ action Λ dispatch •
validationSuccess • validationFailure
# 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
# 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
Complete!
Pros • Fat component/container ͷճආ • ಠཱͨ͠ػߏͰ࣮ ≒ ͷ •
֎෦ϥΠϒϥϦͷґଘճආ • Ұͭͷػߏʹ validation Λू
Cons • Component ͔Βԕ͍ॴʹ validation ͕࣮ ͞ΕΔ • middleware ΛΒͳ͍ͱཧղ͕͍͠
Source https://github.com/kato1628/frontend-validation
Thank you!