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
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
Agentic Software Factoryに、すごく賢いIF文を。 / super smart IF statement into the Agentic Software Factory.
rkaga
8
1.9k
Heart of Swift Concurrency
koher
0
1.2k
[2026-09-26]空論ジェネリックプロセス~テスト資産とAIで紡ぐ、再現可能なパフォーマンスチューニングの話~
tosite
0
260
Ghostty + Neovimで作る 透明でカッコ良い開発環境
j341nono
0
150
モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった ? / is-the-business-domain-the-real-complexity
hatsu38
0
450
UPDATE をやめる — EF Core でマスタをバージョン管理する
panda728
PRO
0
1.1k
Vue Fes Japan の “作る側”に関わってみて
naokihaba
0
110
そのリトライ、死んだコネクションを使い回していませんか ── GoのHTTPクライアントとHTTP/2を実プロダクト障害から学び直す
myus4a
0
390
動作中のプログラムの中身をリアルタイムに覗く / Realtime Debugger for CSharp with Roslyn
prota
1
1.8k
Agents on Rails - Rails at Scale 2026
irinanazarova
0
340
仕様駆動開発による爆速プロダクト開発 / Bakusoku Spec Driven Development
kobakei
0
200
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
540
Featured
See All Featured
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.7k
How to train your dragon (web standard)
notwaldorf
96
6.9k
Writing Fast Ruby
sferik
630
63k
From π to Pie charts
rasagy
1
390
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
2
930
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
1k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Into the Great Unknown - MozCon
thekraken
41
2.8k
Ten Tips & Tricks for a 🌱 transition
stuffmc
1
250
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
460
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!