CINXE.COM
<!doctype html><html lang="en"><head><title data-rh="true">Best Practices for Flow Typing React Components | by Coursera | Coursera Engineering | Medium</title><meta data-rh="true" charset="utf-8"/><meta data-rh="true" name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1,maximum-scale=1"/><meta data-rh="true" name="theme-color" content="#000000"/><meta data-rh="true" name="twitter:app:name:iphone" content="Medium"/><meta data-rh="true" name="twitter:app:id:iphone" content="828256236"/><meta data-rh="true" property="al:ios:app_name" content="Medium"/><meta data-rh="true" property="al:ios:app_store_id" content="828256236"/><meta data-rh="true" property="al:android:package" content="com.medium.reader"/><meta data-rh="true" property="fb:app_id" content="542599432471018"/><meta data-rh="true" property="og:site_name" content="Medium"/><meta data-rh="true" property="og:type" content="article"/><meta data-rh="true" property="article:published_time" content="2018-04-26T18:48:23.322Z"/><meta data-rh="true" name="title" content="Best Practices for Flow Typing React Components | by Coursera | Coursera Engineering | Medium"/><meta data-rh="true" property="og:title" content="Best Practices for Flow Typing React Components"/><meta data-rh="true" property="al:android:url" content="medium://p/5af62a82b4df"/><meta data-rh="true" property="al:ios:url" content="medium://p/5af62a82b4df"/><meta data-rh="true" property="al:android:app_name" content="Medium"/><meta data-rh="true" name="description" content="At Coursera, we use Flow to type our Javascript and catch mistakes at compile time. Flow has been enormously useful as a documentation tool and has increased the productivity of our frontend…"/><meta data-rh="true" property="og:description" content="By David Winegar"/><meta data-rh="true" property="og:url" content="https://medium.com/coursera-engineering/best-practices-for-flow-typing-react-components-5af62a82b4df"/><meta data-rh="true" property="al:web:url" content="https://medium.com/coursera-engineering/best-practices-for-flow-typing-react-components-5af62a82b4df"/><meta data-rh="true" property="article:author" content="https://medium.com/@CourseraEng"/><meta data-rh="true" name="author" content="Coursera"/><meta data-rh="true" name="robots" content="index,noarchive,follow,max-image-preview:large"/><meta data-rh="true" name="referrer" content="unsafe-url"/><meta data-rh="true" property="twitter:title" content="Best Practices for Flow Typing React Components"/><meta data-rh="true" name="twitter:site" content="@CourseraEng"/><meta data-rh="true" name="twitter:app:url:iphone" content="medium://p/5af62a82b4df"/><meta data-rh="true" property="twitter:description" content="By David Winegar"/><meta data-rh="true" name="twitter:card" content="summary"/><meta data-rh="true" name="twitter:label1" content="Reading time"/><meta data-rh="true" name="twitter:data1" content="4 min read"/><link data-rh="true" rel="icon" href="https://miro.medium.com/v2/5d8de952517e8160e40ef9841c781cdc14a5db313057fa3c3de41c6f5b494b19"/><link data-rh="true" rel="search" type="application/opensearchdescription+xml" title="Medium" href="/osd.xml"/><link data-rh="true" rel="apple-touch-icon" sizes="152x152" href="https://miro.medium.com/v2/resize:fill:304:304/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="120x120" href="https://miro.medium.com/v2/resize:fill:240:240/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="76x76" href="https://miro.medium.com/v2/resize:fill:152:152/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="60x60" href="https://miro.medium.com/v2/resize:fill:120:120/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="mask-icon" href="https://miro.medium.com/v2/resize:fill:1000:1000/7*GAOKVe--MXbEJmV9230oOQ.png" color="#171717"/><link data-rh="true" rel="preconnect" href="https://glyph.medium.com" crossOrigin=""/><link data-rh="true" id="glyph_preload_link" rel="preload" as="style" type="text/css" href="https://glyph.medium.com/css/unbound.css"/><link data-rh="true" id="glyph_link" rel="stylesheet" type="text/css" href="https://glyph.medium.com/css/unbound.css"/><link data-rh="true" rel="author" href="https://medium.com/@CourseraEng"/><link data-rh="true" rel="canonical" href="https://medium.com/coursera-engineering/best-practices-for-flow-typing-react-components-5af62a82b4df"/><link data-rh="true" rel="alternate" href="android-app://com.medium.reader/https/medium.com/p/5af62a82b4df"/><script data-rh="true" type="application/ld+json">{"@context":"http:\u002F\u002Fschema.org","@type":"NewsArticle","image":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fda:true\u002Fbd978bb536350a710e8efb012513429cabdc4c28700604261aeda246d0f980b7","height":810,"width":1440},"url":"https:\u002F\u002Fmedium.com\u002Fcoursera-engineering\u002Fbest-practices-for-flow-typing-react-components-5af62a82b4df","dateCreated":"2017-06-01T00:00:00.000Z","datePublished":"2017-06-01T00:00:00.000Z","dateModified":"2018-06-12T18:32:51.304Z","headline":"Best Practices for Flow Typing React Components - Coursera Engineering - Medium","name":"Best Practices for Flow Typing React Components - Coursera Engineering - Medium","description":"At Coursera, we use Flow to type our Javascript and catch mistakes at compile time. Flow has been enormously useful as a documentation tool and has increased the productivity of our frontend…","identifier":"5af62a82b4df","author":{"@type":"Person","name":"Coursera","url":"https:\u002F\u002Fmedium.com\u002F@CourseraEng"},"creator":["Coursera"],"publisher":{"@type":"Organization","name":"Coursera Engineering","url":"https:\u002F\u002Fmedium.com\u002Fcoursera-engineering","logo":{"@type":"ImageObject","width":422,"height":60,"url":"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:844\u002F1*zXjOKA4JKHH04Ipi2NI0jA.png"}},"mainEntityOfPage":"https:\u002F\u002Fmedium.com\u002Fcoursera-engineering\u002Fbest-practices-for-flow-typing-react-components-5af62a82b4df"}</script><style type="text/css" data-fela-rehydration="515" data-fela-type="STATIC">html{box-sizing:border-box;-webkit-text-size-adjust:100%}*, *:before, *:after{box-sizing:inherit}body{margin:0;padding:0;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;color:rgba(0,0,0,0.8);position:relative;min-height:100vh}h1, h2, h3, h4, h5, h6, dl, dd, ol, ul, menu, figure, blockquote, p, pre, form{margin:0}menu, ol, ul{padding:0;list-style:none;list-style-image:none}main{display:block}a{color:inherit;text-decoration:none}a, button, input{-webkit-tap-highlight-color:transparent}img, svg{vertical-align:middle}button{background:transparent;overflow:visible}button, input, optgroup, select, textarea{margin:0}:root{--reach-tabs:1;--reach-menu-button:1}#speechify-root{font-family:Sohne, sans-serif}div[data-popper-reference-hidden="true"]{visibility:hidden;pointer-events:none}.grecaptcha-badge{visibility:hidden} /*XCode style (c) Angel Garcia <angelgarcia.mail@gmail.com>*/.hljs {background: #fff;color: black; }/* Gray DOCTYPE selectors like WebKit */ .xml .hljs-meta {color: #c0c0c0; }.hljs-comment, .hljs-quote {color: #007400; }.hljs-tag, .hljs-attribute, .hljs-keyword, .hljs-selector-tag, .hljs-literal, .hljs-name {color: #aa0d91; }.hljs-variable, .hljs-template-variable {color: #3F6E74; }.hljs-code, .hljs-string, .hljs-meta .hljs-string {color: #c41a16; }.hljs-regexp, .hljs-link {color: #0E0EFF; }.hljs-title, .hljs-symbol, .hljs-bullet, .hljs-number {color: #1c00cf; }.hljs-section, .hljs-meta {color: #643820; }.hljs-title.class_, .hljs-class .hljs-title, .hljs-type, .hljs-built_in, .hljs-params {color: #5c2699; }.hljs-attr {color: #836C28; }.hljs-subst {color: #000; }.hljs-formula {background-color: #eee;font-style: italic; }.hljs-addition {background-color: #baeeba; }.hljs-deletion {background-color: #ffc8bd; }.hljs-selector-id, .hljs-selector-class {color: #9b703f; }.hljs-doctag, .hljs-strong {font-weight: bold; }.hljs-emphasis {font-style: italic; } </style><style type="text/css" data-fela-rehydration="515" data-fela-type="KEYFRAME">@-webkit-keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}@-moz-keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}@keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}</style><style type="text/css" data-fela-rehydration="515" data-fela-type="RULE">.a{font-family:medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif}.b{font-weight:400}.c{background-color:rgba(255, 255, 255, 1)}.l{display:block}.m{position:sticky}.n{top:0}.o{z-index:500}.p{padding:0 24px}.q{align-items:center}.r{border-bottom:solid 1px #F2F2F2}.y{height:41px}.z{line-height:20px}.ab{display:flex}.ac{height:57px}.ae{flex:1 0 auto}.af{color:inherit}.ag{fill:inherit}.ah{font-size:inherit}.ai{border:inherit}.aj{font-family:inherit}.ak{letter-spacing:inherit}.al{font-weight:inherit}.am{padding:0}.an{margin:0}.ao{cursor:pointer}.ap:disabled{cursor:not-allowed}.aq:disabled{color:#6B6B6B}.ar:disabled{fill:#6B6B6B}.au{width:auto}.av path{fill:#242424}.aw{height:25px}.ax{margin-left:16px}.ay{border:none}.az{border-radius:20px}.ba{width:240px}.bb{background:#F9F9F9}.bc path{fill:#6B6B6B}.be{outline:none}.bf{font-family:sohne, "Helvetica Neue", Helvetica, Arial, sans-serif}.bg{font-size:14px}.bh{width:100%}.bi{padding:10px 20px 10px 0}.bj{background-color:transparent}.bk{color:#242424}.bl::placeholder{color:#6B6B6B}.bm{display:inline-block}.bn{margin-left:12px}.bo{margin-right:12px}.bp{border-radius:4px}.bq{margin-left:24px}.br{height:24px}.bx{background-color:#F9F9F9}.by{border-radius:50%}.bz{height:32px}.ca{width:32px}.cb{justify-content:center}.ch{max-width:680px}.ci{min-width:0}.cj{animation:k1 1.2s ease-in-out infinite}.ck{height:100vh}.cl{margin-bottom:16px}.cm{margin-top:48px}.cn{align-items:flex-start}.co{flex-direction:column}.cp{justify-content:space-between}.cq{margin-bottom:24px}.cw{width:80%}.cx{background-color:#F2F2F2}.dd{height:44px}.de{width:44px}.df{margin:auto 0}.dg{margin-bottom:4px}.dh{height:16px}.di{width:120px}.dj{width:80px}.dp{margin-bottom:8px}.dq{width:96%}.dr{width:98%}.ds{width:81%}.dt{margin-left:8px}.du{color:#6B6B6B}.dv{font-size:13px}.dw{height:100%}.ep{color:#FFFFFF}.eq{fill:#FFFFFF}.er{background:rgba(99, 136, 191, 1)}.es{border-color:rgba(99, 136, 191, 1)}.ew:disabled{cursor:inherit !important}.ex:disabled{opacity:0.3}.ey:disabled:hover{background:rgba(99, 136, 191, 1)}.ez:disabled:hover{border-color:rgba(99, 136, 191, 1)}.fa{border-radius:99em}.fb{border-width:1px}.fc{border-style:solid}.fd{box-sizing:border-box}.fe{text-decoration:none}.ff{text-align:center}.fi{margin-right:32px}.fj{position:relative}.fk{fill:#6B6B6B}.fn{background:transparent}.fo svg{margin-left:4px}.fp svg{fill:#6B6B6B}.fr{box-shadow:inset 0 0 0 1px rgba(0, 0, 0, 0.05)}.fs{position:absolute}.fz{margin:0 24px}.gd{background:rgba(255, 255, 255, 1)}.ge{border:1px solid #F2F2F2}.gf{box-shadow:0 1px 4px #F2F2F2}.gg{max-height:100vh}.gh{overflow-y:auto}.gi{left:0}.gj{top:calc(100vh + 100px)}.gk{bottom:calc(100vh + 100px)}.gl{width:10px}.gm{pointer-events:none}.gn{word-break:break-word}.go{word-wrap:break-word}.gp:after{display:block}.gq:after{content:""}.gr:after{clear:both}.gs{line-height:1.23}.gt{letter-spacing:0}.gu{font-style:normal}.gv{font-weight:700}.ia{align-items:baseline}.ib{width:48px}.ic{height:48px}.id{border:2px solid rgba(255, 255, 255, 1)}.ie{z-index:0}.if{box-shadow:none}.ig{border:1px solid rgba(0, 0, 0, 0.05)}.ih{margin-left:-12px}.ii{width:28px}.ij{height:28px}.ik{z-index:1}.il{width:24px}.im{margin-bottom:2px}.in{flex-wrap:nowrap}.io{font-size:16px}.ip{line-height:24px}.ir{margin:0 8px}.is{display:inline}.it{color:rgba(99, 136, 191, 1)}.iu{fill:rgba(99, 136, 191, 1)}.ix{flex:0 0 auto}.ja{flex-wrap:wrap}.jd{white-space:pre-wrap}.je{margin-right:4px}.jf{overflow:hidden}.jg{max-height:20px}.jh{text-overflow:ellipsis}.ji{display:-webkit-box}.jj{-webkit-line-clamp:1}.jk{-webkit-box-orient:vertical}.jl{word-break:break-all}.jn{padding-left:8px}.jo{padding-right:8px}.kp> *{flex-shrink:0}.kq{overflow-x:scroll}.kr::-webkit-scrollbar{display:none}.ks{scrollbar-width:none}.kt{-ms-overflow-style:none}.ku{width:74px}.kv{flex-direction:row}.kw{z-index:2}.kz{-webkit-user-select:none}.la{border:0}.lb{fill:rgba(117, 117, 117, 1)}.le{outline:0}.lf{user-select:none}.lg> svg{pointer-events:none}.lp{cursor:progress}.lq{opacity:1}.lr{padding:4px 0}.lu{margin-top:0px}.lv{width:16px}.lx{display:inline-flex}.md{max-width:100%}.me{padding:8px 2px}.mf svg{color:#6B6B6B}.mw{line-height:1.58}.mx{letter-spacing:-0.004em}.my{font-family:source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif}.nt{margin-bottom:-0.46em}.nu{font-style:italic}.nv{text-decoration:underline}.nw{line-height:1.12}.nx{letter-spacing:-0.022em}.ny{font-weight:600}.ot{margin-bottom:-0.28em}.oz{list-style-type:disc}.pa{margin-left:30px}.pb{padding-left:0px}.ph{list-style-type:decimal}.pi{padding:2px 4px}.pj{font-size:75%}.pk> strong{font-family:inherit}.pl{font-family:source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace}.pm{margin-bottom:26px}.pn{margin-top:6px}.po{margin-top:8px}.pp{margin-right:8px}.pq{padding:8px 16px}.pr{border-radius:100px}.ps{transition:background 300ms ease}.pu{white-space:nowrap}.pv{border-top:none}.qb{height:52px}.qc{max-height:52px}.qd{box-sizing:content-box}.qe{position:static}.qg{max-width:155px}.qm{margin-right:20px}.qs{margin-bottom:48px}.rg{border-radius:2px}.ri{height:64px}.rj{width:64px}.rk{align-self:flex-end}.rl{flex:1 1 auto}.rr{padding-right:4px}.rs{font-weight:500}.sf{margin-top:16px}.sg{color:rgba(255, 255, 255, 1)}.sh{fill:rgba(255, 255, 255, 1)}.si{background:rgba(25, 25, 25, 1)}.sj{border-color:rgba(25, 25, 25, 1)}.sm:disabled{opacity:0.1}.sn:disabled:hover{background:rgba(25, 25, 25, 1)}.so:disabled:hover{border-color:rgba(25, 25, 25, 1)}.sp{height:0px}.sq{border-bottom:solid 1px #E5E5E5}.sr{margin-top:56px}.ss{margin-top:72px}.st{padding:24px 0}.su{margin-bottom:0px}.sv{margin-right:16px}.as:hover:not(:disabled){color:rgba(25, 25, 25, 1)}.at:hover:not(:disabled){fill:rgba(25, 25, 25, 1)}.et:hover{background:rgba(87, 117, 161, 1)}.eu:hover{border-color:rgba(87, 117, 161, 1)}.ev:hover{cursor:pointer}.fl:hover{color:#242424}.fm:hover{fill:#242424}.fq:hover svg{fill:#242424}.ft:hover{background-color:rgba(0, 0, 0, 0.1)}.iq:hover{text-decoration:underline}.iv:hover:not(:disabled){color:rgba(87, 117, 161, 1)}.iw:hover:not(:disabled){fill:rgba(87, 117, 161, 1)}.ld:hover{fill:rgba(8, 8, 8, 1)}.ls:hover{fill:#000000}.lt:hover p{color:#000000}.lw:hover{color:#000000}.mg:hover svg{color:#000000}.pt:hover{background-color:#F2F2F2}.rh:hover{background-color:none}.sk:hover{background:#000000}.sl:hover{border-color:#242424}.bd:focus-within path{fill:#242424}.lc:focus{fill:rgba(8, 8, 8, 1)}.mh:focus svg{color:#000000}.lh:active{border-style:none}</style><style type="text/css" data-fela-rehydration="515" data-fela-type="RULE" media="all and (min-width: 1080px)">.d{display:none}.bw{width:64px}.cg{margin:0 64px}.cv{height:48px}.dc{margin-bottom:52px}.do{margin-bottom:48px}.ef{font-size:14px}.eg{line-height:20px}.em{font-size:13px}.eo{padding:5px 12px}.fh{display:flex}.fy{margin-bottom:68px}.gc{max-width:680px}.hq{font-size:42px}.hr{margin-top:1.19em}.hs{margin-bottom:32px}.ht{line-height:52px}.hu{letter-spacing:-0.011em}.hz{align-items:center}.kb{border-top:solid 1px #F2F2F2}.kc{border-bottom:solid 1px #F2F2F2}.kd{margin:32px 0 0}.ke{padding:3px 8px}.kn> *{margin-right:24px}.ko> :last-child{margin-right:0}.lo{margin-top:0px}.mc{margin:0}.np{font-size:20px}.nq{margin-top:2.14em}.nr{line-height:32px}.ns{letter-spacing:-0.003em}.op{font-size:24px}.oq{margin-top:1.95em}.or{line-height:30px}.os{letter-spacing:-0.016em}.oy{margin-top:0.94em}.pg{margin-top:1.14em}.qa{margin-bottom:88px}.ql{display:inline-block}.qr{padding-top:72px}.qt{flex-direction:row}.qw{margin-bottom:0}.qx{margin-right:20px}.rm{max-width:500px}.sd{line-height:24px}.se{letter-spacing:0}</style><style type="text/css" data-fela-rehydration="515" data-fela-type="RULE" media="all and (max-width: 1079.98px)">.e{display:none}.ln{margin-top:0px}.qk{display:inline-block}</style><style type="text/css" data-fela-rehydration="515" data-fela-type="RULE" media="all and (max-width: 903.98px)">.f{display:none}.lm{margin-top:0px}.qj{display:inline-block}</style><style type="text/css" data-fela-rehydration="515" data-fela-type="RULE" media="all and (max-width: 727.98px)">.g{display:none}.lk{margin-top:0px}.ll{margin-right:0px}.qi{display:inline-block}</style><style type="text/css" data-fela-rehydration="515" data-fela-type="RULE" media="all and (max-width: 551.98px)">.h{display:none}.s{display:flex}.t{justify-content:space-between}.bs{width:24px}.cc{margin:0 24px}.cr{height:40px}.cy{margin-bottom:44px}.dk{margin-bottom:32px}.dx{font-size:13px}.dy{line-height:20px}.eh{padding:0px 8px 1px}.fu{margin-bottom:4px}.gw{font-size:32px}.gx{margin-top:1.01em}.gy{margin-bottom:24px}.gz{line-height:38px}.ha{letter-spacing:-0.014em}.hv{align-items:flex-start}.iy{flex-direction:column}.jb{margin-bottom:2px}.jp{margin:24px -24px 0}.jq{padding:0}.kf> *{margin-right:8px}.kg> :last-child{margin-right:24px}.kx{margin-left:0px}.li{margin-top:0px}.lj{margin-right:0px}.ly{margin:0}.mi{border:1px solid #F2F2F2}.mj{border-radius:99em}.mk{padding:0px 16px 0px 12px}.ml{height:38px}.mm{align-items:center}.mo svg{margin-right:8px}.mz{font-size:18px}.na{margin-top:1.56em}.nb{line-height:28px}.nc{letter-spacing:-0.003em}.nz{font-size:20px}.oa{margin-top:1.2em}.ob{line-height:24px}.oc{letter-spacing:0}.ou{margin-top:0.67em}.pc{margin-top:1.34em}.pw{margin-bottom:80px}.qh{display:inline-block}.qn{padding-top:48px}.re{margin-bottom:20px}.rf{margin-right:0}.rq{max-width:100%}.rt{font-size:24px}.ru{line-height:30px}.rv{letter-spacing:-0.016em}.mn:hover{border-color:#E5E5E5}</style><style type="text/css" data-fela-rehydration="515" data-fela-type="RULE" media="all and (min-width: 904px) and (max-width: 1079.98px)">.i{display:none}.bv{width:64px}.cf{margin:0 64px}.cu{height:48px}.db{margin-bottom:52px}.dn{margin-bottom:48px}.ed{font-size:14px}.ee{line-height:20px}.ek{font-size:13px}.el{padding:5px 12px}.fg{display:flex}.fx{margin-bottom:68px}.gb{max-width:680px}.hl{font-size:42px}.hm{margin-top:1.19em}.hn{margin-bottom:32px}.ho{line-height:52px}.hp{letter-spacing:-0.011em}.hy{align-items:center}.jx{border-top:solid 1px #F2F2F2}.jy{border-bottom:solid 1px #F2F2F2}.jz{margin:32px 0 0}.ka{padding:3px 8px}.kl> *{margin-right:24px}.km> :last-child{margin-right:0}.mb{margin:0}.nl{font-size:20px}.nm{margin-top:2.14em}.nn{line-height:32px}.no{letter-spacing:-0.003em}.ol{font-size:24px}.om{margin-top:1.95em}.on{line-height:30px}.oo{letter-spacing:-0.016em}.ox{margin-top:0.94em}.pf{margin-top:1.14em}.pz{margin-bottom:88px}.qq{padding-top:72px}.qu{flex-direction:row}.qy{margin-bottom:0}.qz{margin-right:20px}.rn{max-width:500px}.sb{line-height:24px}.sc{letter-spacing:0}</style><style type="text/css" data-fela-rehydration="515" data-fela-type="RULE" media="all and (min-width: 728px) and (max-width: 903.98px)">.j{display:none}.w{display:flex}.x{justify-content:space-between}.bu{width:64px}.ce{margin:0 48px}.ct{height:48px}.da{margin-bottom:52px}.dm{margin-bottom:48px}.eb{font-size:13px}.ec{line-height:20px}.ej{padding:0px 8px 1px}.fw{margin-bottom:68px}.ga{max-width:680px}.hg{font-size:42px}.hh{margin-top:1.19em}.hi{margin-bottom:32px}.hj{line-height:52px}.hk{letter-spacing:-0.011em}.hx{align-items:center}.jt{border-top:solid 1px #F2F2F2}.ju{border-bottom:solid 1px #F2F2F2}.jv{margin:32px 0 0}.jw{padding:3px 8px}.kj> *{margin-right:24px}.kk> :last-child{margin-right:0}.ma{margin:0}.nh{font-size:20px}.ni{margin-top:2.14em}.nj{line-height:32px}.nk{letter-spacing:-0.003em}.oh{font-size:24px}.oi{margin-top:1.95em}.oj{line-height:30px}.ok{letter-spacing:-0.016em}.ow{margin-top:0.94em}.pe{margin-top:1.14em}.py{margin-bottom:88px}.qp{padding-top:72px}.qv{flex-direction:row}.ra{margin-bottom:0}.rb{margin-right:20px}.ro{max-width:500px}.rz{line-height:24px}.sa{letter-spacing:0}</style><style type="text/css" data-fela-rehydration="515" data-fela-type="RULE" media="all and (min-width: 552px) and (max-width: 727.98px)">.k{display:none}.u{display:flex}.v{justify-content:space-between}.bt{width:24px}.cd{margin:0 24px}.cs{height:40px}.cz{margin-bottom:44px}.dl{margin-bottom:32px}.dz{font-size:13px}.ea{line-height:20px}.ei{padding:0px 8px 1px}.fv{margin-bottom:4px}.hb{font-size:32px}.hc{margin-top:1.01em}.hd{margin-bottom:24px}.he{line-height:38px}.hf{letter-spacing:-0.014em}.hw{align-items:flex-start}.iz{flex-direction:column}.jc{margin-bottom:2px}.jr{margin:24px 0 0}.js{padding:0}.kh> *{margin-right:8px}.ki> :last-child{margin-right:8px}.ky{margin-left:0px}.lz{margin:0}.mp{border:1px solid #F2F2F2}.mq{border-radius:99em}.mr{padding:0px 16px 0px 12px}.ms{height:38px}.mt{align-items:center}.mv svg{margin-right:8px}.nd{font-size:18px}.ne{margin-top:1.56em}.nf{line-height:28px}.ng{letter-spacing:-0.003em}.od{font-size:20px}.oe{margin-top:1.2em}.of{line-height:24px}.og{letter-spacing:0}.ov{margin-top:0.67em}.pd{margin-top:1.34em}.px{margin-bottom:80px}.qo{padding-top:48px}.rc{margin-bottom:20px}.rd{margin-right:0}.rp{max-width:100%}.rw{font-size:24px}.rx{line-height:30px}.ry{letter-spacing:-0.016em}.mu:hover{border-color:#E5E5E5}</style><style type="text/css" data-fela-rehydration="515" data-fela-type="RULE" media="print">.qf{display:none}</style><style type="text/css" data-fela-rehydration="515" data-fela-type="RULE" media="(orientation: landscape) and (max-width: 903.98px)">.jm{max-height:none}</style></head><body><div id="root"><div class="a b c"><div class="d e f g h i j k"></div><script>document.domain = document.domain;</script><div class="l c"><div class="l m n o c"><div class="p q r s t u v w x i d y z"><a class="du ag dv bf ak b am an ao ap aq ar as at s u w i d q dw z" href="https://rsci.app.link/?%24canonical_url=https%3A%2F%2Fmedium.com%2Fp%2F5af62a82b4df&%7Efeature=LoOpenInAppButton&%7Echannel=ShowPostUnderCollection&source=---top_nav_layout_nav----------------------------------" rel="noopener follow">Open in app<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" fill="none" viewBox="0 0 10 10" class="dt"><path fill="currentColor" d="M.985 8.485a.375.375 0 1 0 .53.53zM8.75 1.25h.375A.375.375 0 0 0 8.75.875zM8.375 6.5a.375.375 0 1 0 .75 0zM3.5.875a.375.375 0 1 0 0 .75zm-1.985 8.14 7.5-7.5-.53-.53-7.5 7.5zm6.86-7.765V6.5h.75V1.25zM3.5 1.625h5.25v-.75H3.5z"></path></svg></a><div class="ab q"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><button class="bf b dx dy eh dz ea ei eb ec ej ek ee el em eg eo ep eq er es et eu ev ew ex ey ez fa fb fc fd bm fe ff" data-testid="headerSignUpButton">Sign up</button></span></p><div class="ax l"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSignInButton" rel="noopener follow" href="/m/signin?operation=login&redirect=https%3A%2F%2Fmedium.com%2Fcoursera-engineering%2Fbest-practices-for-flow-typing-react-components-5af62a82b4df&source=post_page---top_nav_layout_nav-----------------------global_nav-----------">Sign in</a></span></p></div></div></div><div class="p q r ab ac"><div class="ab q ae"><a class="af ag ah ai aj ak al am an ao ap aq ar as at ab" aria-label="Homepage" data-testid="headerMediumLogo" rel="noopener follow" href="/?source=---top_nav_layout_nav----------------------------------"><svg xmlns="http://www.w3.org/2000/svg" width="719" height="160" fill="none" viewBox="0 0 719 160" class="au av aw"><path fill="#242424" d="m174.104 9.734.215-.047V8.02H130.39L89.6 103.89 48.81 8.021H1.472v1.666l.212.047c8.018 1.81 12.09 4.509 12.09 14.242V137.93c0 9.734-4.087 12.433-12.106 14.243l-.212.047v1.671h32.118v-1.665l-.213-.048c-8.018-1.809-12.089-4.509-12.089-14.242V30.586l52.399 123.305h2.972l53.925-126.743V140.75c-.687 7.688-4.721 10.062-11.982 11.701l-.215.05v1.652h55.948v-1.652l-.215-.05c-7.269-1.639-11.4-4.013-12.087-11.701l-.037-116.774h.037c0-9.733 4.071-12.432 12.087-14.242m25.555 75.488c.915-20.474 8.268-35.252 20.606-35.507 3.806.063 6.998 1.312 9.479 3.714 5.272 5.118 7.751 15.812 7.368 31.793zm-.553 5.77h65.573v-.275c-.186-15.656-4.721-27.834-13.466-36.196-7.559-7.227-18.751-11.203-30.507-11.203h-.263c-6.101 0-13.584 1.48-18.909 4.16-6.061 2.807-11.407 7.003-15.855 12.511-7.161 8.874-11.499 20.866-12.554 34.343q-.05.606-.092 1.212a50 50 0 0 0-.065 1.151 85.807 85.807 0 0 0-.094 5.689c.71 30.524 17.198 54.917 46.483 54.917 25.705 0 40.675-18.791 44.407-44.013l-1.886-.664c-6.557 13.556-18.334 21.771-31.738 20.769-18.297-1.369-32.314-19.922-31.042-42.395m139.722 41.359c-2.151 5.101-6.639 7.908-12.653 7.908s-11.513-4.129-15.418-11.63c-4.197-8.053-6.405-19.436-6.405-32.92 0-28.067 8.729-46.22 22.24-46.22 5.657 0 10.111 2.807 12.236 7.704zm43.499 20.008c-8.019-1.897-12.089-4.722-12.089-14.951V1.309l-48.716 14.353v1.757l.299-.024c6.72-.543 11.278.386 13.925 2.83 2.072 1.915 3.082 4.853 3.082 8.987v18.66c-4.803-3.067-10.516-4.56-17.448-4.56-14.059 0-26.909 5.92-36.176 16.672-9.66 11.205-14.767 26.518-14.767 44.278-.003 31.72 15.612 53.039 38.851 53.039 13.595 0 24.533-7.449 29.54-20.013v16.865h43.711v-1.746zM424.1 19.819c0-9.904-7.468-17.374-17.375-17.374-9.859 0-17.573 7.632-17.573 17.374s7.721 17.374 17.573 17.374c9.907 0 17.375-7.47 17.375-17.374m11.499 132.546c-8.019-1.897-12.089-4.722-12.089-14.951h-.035V43.635l-43.714 12.551v1.705l.263.024c9.458.842 12.047 4.1 12.047 15.152v81.086h43.751v-1.746zm112.013 0c-8.018-1.897-12.089-4.722-12.089-14.951V43.635l-41.621 12.137v1.71l.246.026c7.733.813 9.967 4.257 9.967 15.36v59.279c-2.578 5.102-7.415 8.131-13.274 8.336-9.503 0-14.736-6.419-14.736-18.073V43.638l-43.714 12.55v1.703l.262.024c9.459.84 12.05 4.097 12.05 15.152v50.17a56.3 56.3 0 0 0 .91 10.444l.787 3.423c3.701 13.262 13.398 20.197 28.59 20.197 12.868 0 24.147-7.966 29.115-20.43v17.311h43.714v-1.747zm169.818 1.788v-1.749l-.213-.05c-8.7-2.006-12.089-5.789-12.089-13.49v-63.79c0-19.89-11.171-31.761-29.883-31.761-13.64 0-25.141 7.882-29.569 20.16-3.517-13.01-13.639-20.16-28.606-20.16-13.146 0-23.449 6.938-27.869 18.657V43.643L545.487 55.68v1.715l.263.024c9.345.829 12.047 4.181 12.047 14.95v81.784h40.787v-1.746l-.215-.053c-6.941-1.631-9.181-4.606-9.181-12.239V66.998c1.836-4.289 5.537-9.37 12.853-9.37 9.086 0 13.692 6.296 13.692 18.697v77.828h40.797v-1.746l-.215-.053c-6.94-1.631-9.18-4.606-9.18-12.239V75.066a42 42 0 0 0-.578-7.26c1.947-4.661 5.86-10.177 13.475-10.177 9.214 0 13.691 6.114 13.691 18.696v77.828z"></path></svg></a><div class="ax h"><div class="ab ay az ba bb q bc bd"><div class="bm" aria-hidden="false" aria-describedby="searchResults" aria-labelledby="searchResults"></div><div class="bn bo ab"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M4.092 11.06a6.95 6.95 0 1 1 13.9 0 6.95 6.95 0 0 1-13.9 0m6.95-8.05a8.05 8.05 0 1 0 5.13 14.26l3.75 3.75a.56.56 0 1 0 .79-.79l-3.73-3.73A8.05 8.05 0 0 0 11.042 3z" clip-rule="evenodd"></path></svg></div><input role="combobox" aria-controls="searchResults" aria-expanded="false" aria-label="search" data-testid="headerSearchInput" tabindex="0" class="ay be bf bg z bh bi bj bk bl" placeholder="Search" value=""/></div></div></div><div class="h k w fg fh"><div class="fi ab"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerWriteButton" rel="noopener follow" href="/m/signin?operation=register&redirect=https%3A%2F%2Fmedium.com%2Fnew-story&source=---top_nav_layout_nav-----------------------new_post_topnav-----------"><div class="bf b bg z du fj fk ab q fl fm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24" aria-label="Write"><path fill="currentColor" d="M14 4a.5.5 0 0 0 0-1zm7 6a.5.5 0 0 0-1 0zm-7-7H4v1h10zM3 4v16h1V4zm1 17h16v-1H4zm17-1V10h-1v10zm-1 1a1 1 0 0 0 1-1h-1zM3 20a1 1 0 0 0 1 1v-1zM4 3a1 1 0 0 0-1 1h1z"></path><path stroke="currentColor" d="m17.5 4.5-8.458 8.458a.25.25 0 0 0-.06.098l-.824 2.47a.25.25 0 0 0 .316.316l2.47-.823a.25.25 0 0 0 .098-.06L19.5 6.5m-2-2 2.323-2.323a.25.25 0 0 1 .354 0l1.646 1.646a.25.25 0 0 1 0 .354L19.5 6.5m-2-2 2 2"></path></svg><div class="dt l">Write</div></div></a></span></div></div><div class="k j i d"><div class="fi ab"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSearchButton" rel="noopener follow" href="/search?source=---top_nav_layout_nav----------------------------------"><div class="bf b bg z du fj fk ab q fl fm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24" aria-label="Search"><path fill="currentColor" fill-rule="evenodd" d="M4.092 11.06a6.95 6.95 0 1 1 13.9 0 6.95 6.95 0 0 1-13.9 0m6.95-8.05a8.05 8.05 0 1 0 5.13 14.26l3.75 3.75a.56.56 0 1 0 .79-.79l-3.73-3.73A8.05 8.05 0 0 0 11.042 3z" clip-rule="evenodd"></path></svg></div></a></div></div><div class="fi h k j"><div class="ab q"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><button class="bf b dx dy eh dz ea ei eb ec ej ek ee el em eg eo ep eq er es et eu ev ew ex ey ez fa fb fc fd bm fe ff" data-testid="headerSignUpButton">Sign up</button></span></p><div class="ax l"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSignInButton" rel="noopener follow" href="/m/signin?operation=login&redirect=https%3A%2F%2Fmedium.com%2Fcoursera-engineering%2Fbest-practices-for-flow-typing-react-components-5af62a82b4df&source=post_page---top_nav_layout_nav-----------------------global_nav-----------">Sign in</a></span></p></div></div></div><div class="l" aria-hidden="false"><button class="ay fn am ab q ao fo fp fq" aria-label="user options menu" data-testid="headerUserIcon"><div class="l fj"><img alt="" class="l fd by bz ca cx" src="https://miro.medium.com/v2/resize:fill:64:64/1*dmbNkD5D-u45r44go_cf0g.png" width="32" height="32" loading="lazy" role="presentation"/><div class="fr by l bz ca fs n ay ft"></div></div></button></div></div></div><div class="l"><div class="fu fv fw fx fy l"><div class="ab cb"><div class="ci bh fz ga gb gc"></div></div><article><div class="l"><div class="l"><span class="l"></span><section><div><div class="fs gi gj gk gl gm"></div><div class="gn go gp gq gr"><div class="ab cb"><div class="ci bh fz ga gb gc"><div><h1 id="e17a" class="pw-post-title gs gt gu bf gv gw gx gy gz ha hb hc hd he hf hg hh hi hj hk hl hm hn ho hp hq hr hs ht hu bk" data-testid="storyTitle">Best Practices for Flow Typing React Components</h1><div><div class="speechify-ignore ab cp"><div class="speechify-ignore bh l"><div class="hv hw hx hy hz ab"><div><div class="ab ia"><div><div class="bm" aria-hidden="false"><a rel="noopener follow" href="/@CourseraEng?source=post_page---byline--5af62a82b4df--------------------------------"><div class="l ib ic by id ie"><div class="l fj"><img alt="Coursera" class="l fd by dd de cx" src="https://miro.medium.com/v2/resize:fill:88:88/1*j2vLJO9qZg435iRYfd2Mfg.png" width="44" height="44" loading="lazy" data-testid="authorPhoto"/><div class="if by l dd de fs n ig ft"></div></div></div></a></div></div><div class="ih ab fj"><div><div class="bm" aria-hidden="false"><a href="https://medium.com/coursera-engineering?source=post_page---byline--5af62a82b4df--------------------------------" rel="noopener follow"><div class="l ii ij by id ik"><div class="l fj"><img alt="Coursera Engineering" class="l fd by br il cx" src="https://miro.medium.com/v2/resize:fill:48:48/1*j2vLJO9qZg435iRYfd2Mfg.png" width="24" height="24" loading="lazy" data-testid="publicationPhoto"/><div class="if by l br il fs n ig ft"></div></div></div></a></div></div></div></div></div><div class="bn bh l"><div class="ab"><div style="flex:1"><span class="bf b bg z bk"><div class="im ab q"><div class="ab q in"><div class="ab q"><div><div class="bm" aria-hidden="false"><p class="bf b io ip bk"><a class="af ag ah ai aj ak al am an ao ap aq ar iq" data-testid="authorName" rel="noopener follow" href="/@CourseraEng?source=post_page---byline--5af62a82b4df--------------------------------">Coursera</a></p></div></div></div><span class="ir is" aria-hidden="true"><span class="bf b bg z du">·</span></span><p class="bf b io ip du"><span><a class="it iu ah ai aj ak al am an ao ap aq ar ex iv iw" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fsubscribe%2Fuser%2F99c0fb464c1f&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fcoursera-engineering%2Fbest-practices-for-flow-typing-react-components-5af62a82b4df&user=Coursera&userId=99c0fb464c1f&source=post_page-99c0fb464c1f--byline--5af62a82b4df---------------------post_header-----------">Follow</a></span></p></div></div></span></div></div><div class="l ix"><span class="bf b bg z du"><div class="ab cn iy iz ja"><div class="jb jc ab"><div class="bf b bg z du ab jd"><span class="je l ix">Published in</span><div><div class="l" aria-hidden="false"><a class="af ag ah ai aj ak al am an ao ap aq ar iq ab q" data-testid="publicationName" href="https://medium.com/coursera-engineering?source=post_page---byline--5af62a82b4df--------------------------------" rel="noopener follow"><p class="bf b bg z jf jg jh ji jj jk jl jm bk">Coursera Engineering</p></a></div></div></div><div class="h k"><span class="ir is" aria-hidden="true"><span class="bf b bg z du">·</span></span></div></div><span class="bf b bg z du"><div class="ab ae"><span data-testid="storyReadTime">4 min read</span><div class="jn jo l" aria-hidden="true"><span class="l" aria-hidden="true"><span class="bf b bg z du">·</span></span></div><span data-testid="storyPublishDate">Jun 1, 2017</span></div></span></div></span></div></div></div><div class="ab cp jp jq jr js jt ju jv jw jx jy jz ka kb kc kd ke"><div class="h k w fg fh q"><div class="ku l"><div class="ab q kv kw"><div class="pw-multi-vote-icon fj je kx ky kz"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerClapButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fcoursera-engineering%2F5af62a82b4df&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fcoursera-engineering%2Fbest-practices-for-flow-typing-react-components-5af62a82b4df&user=Coursera&userId=99c0fb464c1f&source=---header_actions--5af62a82b4df---------------------clap_footer-----------"><div><div class="bm" aria-hidden="false"><div class="la ao lb lc ld le am lf lg lh kz"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l li lj lk ll lm ln lo"><p class="bf b dv z du"><span class="lp">--</span></p></div></div></div><div><div class="bm" aria-hidden="false"><button class="ao la lq lr ab q fk ls lt" aria-label="responses"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="lu"><path d="M18.006 16.803c1.533-1.456 2.234-3.325 2.234-5.321C20.24 7.357 16.709 4 12.191 4S4 7.357 4 11.482c0 4.126 3.674 7.482 8.191 7.482.817 0 1.622-.111 2.393-.327.231.2.48.391.744.559 1.06.693 2.203 1.044 3.399 1.044.224-.008.4-.112.486-.287a.49.49 0 0 0-.042-.518c-.495-.67-.845-1.364-1.04-2.057a4 4 0 0 1-.125-.598zm-3.122 1.055-.067-.223-.315.096a8 8 0 0 1-2.311.338c-4.023 0-7.292-2.955-7.292-6.587 0-3.633 3.269-6.588 7.292-6.588 4.014 0 7.112 2.958 7.112 6.593 0 1.794-.608 3.469-2.027 4.72l-.195.168v.255c0 .056 0 .151.016.295.025.231.081.478.154.733.154.558.398 1.117.722 1.659a5.3 5.3 0 0 1-2.165-.845c-.276-.176-.714-.383-.941-.59z"></path></svg></button></div></div></div><div class="ab q kf kg kh ki kj kk kl km kn ko kp kq kr ks kt"><div class="lv k j i d"></div><div class="h k"><div><div class="bm" aria-hidden="false"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerBookmarkButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fbookmark%2Fp%2F5af62a82b4df&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fcoursera-engineering%2Fbest-practices-for-flow-typing-react-components-5af62a82b4df&source=---header_actions--5af62a82b4df---------------------bookmark_footer-----------"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="none" viewBox="0 0 25 25" class="du lw" aria-label="Add to list bookmark button"><path fill="currentColor" d="M18 2.5a.5.5 0 0 1 1 0V5h2.5a.5.5 0 0 1 0 1H19v2.5a.5.5 0 1 1-1 0V6h-2.5a.5.5 0 0 1 0-1H18zM7 7a1 1 0 0 1 1-1h3.5a.5.5 0 0 0 0-1H8a2 2 0 0 0-2 2v14a.5.5 0 0 0 .805.396L12.5 17l5.695 4.396A.5.5 0 0 0 19 21v-8.5a.5.5 0 0 0-1 0v7.485l-5.195-4.012a.5.5 0 0 0-.61 0L7 19.985z"></path></svg></a></span></div></div></div><div class="fd lx cn"><div class="l ae"><div class="ab cb"><div class="ly lz ma mb mc md ci bh"><div class="ab"><div class="bm bh" aria-hidden="false"><div><div class="bm" aria-hidden="false"><button aria-label="Listen" data-testid="audioPlayButton" class="af fk ah ai aj ak al me an ao ap ex mf mg lt mh mi mj mk ml s mm mn mo mp mq mr ms u mt mu mv"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M3 12a9 9 0 1 1 18 0 9 9 0 0 1-18 0m9-10C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2m3.376 10.416-4.599 3.066a.5.5 0 0 1-.777-.416V8.934a.5.5 0 0 1 .777-.416l4.599 3.066a.5.5 0 0 1 0 .832" clip-rule="evenodd"></path></svg><div class="j i d"><p class="bf b bg z du">Listen</p></div></button></div></div></div></div></div></div></div></div><div class="bm" aria-hidden="false" aria-describedby="postFooterSocialMenu" aria-labelledby="postFooterSocialMenu"><div><div class="bm" aria-hidden="false"><button aria-controls="postFooterSocialMenu" aria-expanded="false" aria-label="Share Post" data-testid="headerSocialShareButton" class="af fk ah ai aj ak al me an ao ap ex mf mg lt mh mi mj mk ml s mm mn mo mp mq mr ms u mt mu mv"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M15.218 4.931a.4.4 0 0 1-.118.132l.012.006a.45.45 0 0 1-.292.074.5.5 0 0 1-.3-.13l-2.02-2.02v7.07c0 .28-.23.5-.5.5s-.5-.22-.5-.5v-7.04l-2 2a.45.45 0 0 1-.57.04h-.02a.4.4 0 0 1-.16-.3.4.4 0 0 1 .1-.32l2.8-2.8a.5.5 0 0 1 .7 0l2.8 2.79a.42.42 0 0 1 .068.498m-.106.138.008.004v-.01zM16 7.063h1.5a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-11c-1.1 0-2-.9-2-2v-10a2 2 0 0 1 2-2H8a.5.5 0 0 1 .35.15.5.5 0 0 1 .15.35.5.5 0 0 1-.15.35.5.5 0 0 1-.35.15H6.4c-.5 0-.9.4-.9.9v10.2a.9.9 0 0 0 .9.9h11.2c.5 0 .9-.4.9-.9v-10.2c0-.5-.4-.9-.9-.9H16a.5.5 0 0 1 0-1" clip-rule="evenodd"></path></svg><div class="j i d"><p class="bf b bg z du">Share</p></div></button></div></div></div></div></div></div></div></div></div><p id="101b" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">By<em class="nu"> David Winegar</em></p><p id="ecb8" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">At Coursera, we use <a class="af nv" href="https://flow.org/" rel="noopener ugc nofollow" target="_blank">Flow</a> to type our Javascript and catch mistakes at compile time. Flow has been enormously useful as a documentation tool and has increased the productivity of our frontend engineers. However, this tool can be tricky to use with React; it took us several months to figure out how we could truly make our types “flow” from one component to another while still catching errors. We want to share some of our best practices with you so that you can easily type React components, stateless functional components, and higher order components (HOCs).</p><p id="1255" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">Note that this blog post assumes passing familiarity with React and Flow. Flow works with React and JSX <a class="af nv" href="https://flow.org/en/docs/frameworks/react/" rel="noopener ugc nofollow" target="_blank">out of the box</a>, but the types can sometimes be a bit tricky to deal with. For reference, you can take a look at the official Flow library definitions for React <a class="af nv" href="https://github.com/facebook/flow/blob/master/lib/react.js" rel="noopener ugc nofollow" target="_blank">here</a>.</p><h1 id="42fb" class="nw nx gu bf ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot bk">Do I need to use React PropTypes if I use Flow?</h1><p id="2d20" class="pw-post-body-paragraph mw mx gu my b mz ou nb nc nd ov nf ng nh ow nj nk nl ox nn no np oy nr ns nt gn bk">If you use Babel, you should strip your Flow types from your outputted code using the <a class="af nv" href="https://www.npmjs.com/package/babel-plugin-transform-flow-strip-types" rel="noopener ugc nofollow" target="_blank">babel-plugin-transform-flow-strip-types</a>. Usually both React PropTypes and Flow types are stripped out in our production builds. PropTypes provide run-time type checking in the browser console, while Flow types provide compile-time type-checking.</p><ul class=""><li id="505d" class="mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt oz pa pb bk">If you are building a generic UI component that will be used in many places, it’s useful to add both PropTypes and Flow types so that developers see both compile-time errors and the red console PropType warnings when developing.</li><li id="b9c6" class="mw mx gu my b mz pc nb nc nd pd nf ng nh pe nj nk nl pf nn no np pg nr ns nt oz pa pb bk">If you’re building an app that uses Flow types throughout, it’s usually not necessary to also include PropTypes.</li><li id="1246" class="mw mx gu my b mz pc nb nc nd pd nf ng nh pe nj nk nl pf nn no np pg nr ns nt oz pa pb bk">If you are choosing between them, I recommend writing Flow types exclusively. They are usually more specific, easier to write, catch more errors, and can be statically analyzed for correctness without running the code.</li></ul><h1 id="ecc5" class="nw nx gu bf ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot bk">Typing style</h1><p id="0eca" class="pw-post-body-paragraph mw mx gu my b mz ou nb nc nd ov nf ng nh ow nj nk nl ox nn no np oy nr ns nt gn bk">Here are some basic style guidelines for typing React components:</p><ol class=""><li id="3980" class="mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt ph pa pb bk">Prefer using <code class="cx pi pj pk pl b">React.Component<DefaultProps, Props, State></code> over <code class="cx pi pj pk pl b">props: Props; state: State; defaultProps: DefaultProps;</code> in the function body. If <code class="cx pi pj pk pl b">DefaultProps</code> or <code class="cx pi pj pk pl b">State</code> are not used, use <code class="cx pi pj pk pl b">void</code> in their place. We do this for consistency, clarity, and ease of reading the type definition for each React component.</li><li id="aa8f" class="mw mx gu my b mz pc nb nc nd pd nf ng nh pe nj nk nl pf nn no np pg nr ns nt ph pa pb bk">Do not use <code class="cx pi pj pk pl b">*</code> in place of <code class="cx pi pj pk pl b">DefaultProps</code>. Using <code class="cx pi pj pk pl b">*</code> can cause loss of type refinement because Flow expects props passed into a React component are <code class="cx pi pj pk pl b">$Diff<Props, DefaultProps></code>. This can be read as ‘at minimum, the types that are in <code class="cx pi pj pk pl b">Props</code> that are not also in <code class="cx pi pj pk pl b">DefaultProps</code>’. If <code class="cx pi pj pk pl b">*</code> is used, Flow will attempt to infer a <code class="cx pi pj pk pl b">DefaultProps</code> that fits the type definition, even if there are no <code class="cx pi pj pk pl b">DefaultProps</code>, which results in silenced errors.</li><li id="d2a7" class="mw mx gu my b mz pc nb nc nd pd nf ng nh pe nj nk nl pf nn no np pg nr ns nt ph pa pb bk">If you want to use React’s <code class="cx pi pj pk pl b">context</code>, you’ll have to include <code class="cx pi pj pk pl b">contextTypes</code> and also type context yourself, on the class body. Flow doesn’t track passing context and accepts any definition for it.</li><li id="0785" class="mw mx gu my b mz pc nb nc nd pd nf ng nh pe nj nk nl pf nn no np pg nr ns nt ph pa pb bk">If you want to type a function that takes a React component, use the built-in type <code class="cx pi pj pk pl b">React$Component<DefaultProps, Props, State></code>. Ex: <code class="cx pi pj pk pl b">function takeComponentClass(component: Class<React$Component<*, *, *>>): void {};</code>. The built-ino <code class="cx pi pj pk pl b">ReactClass</code> type does not seem to type-check correctly.</li><li id="90c0" class="mw mx gu my b mz pc nb nc nd pd nf ng nh pe nj nk nl pf nn no np pg nr ns nt ph pa pb bk">To type refs correctly, you can use <code class="cx pi pj pk pl b">Element</code> as shown below.</li></ol><p id="af23" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><a class="af nv" href="https://flow.org/try/#0JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wG4AocmATzCTgAUcwBnOAXjgG9y45gAJgC44LGFGAA7AOYUAvhSq16AESSYUAVwA2MJhFYduvfsNHips8gso06cAMowUMepx59NLJFACSZyU0QACMfeUU0bRQWNgBhXEhJJEl4JAAPV0kBNmR0GAA6ePAIJJSAHgA3CEEAGkZmFjqqwQA+Yz40ErEoTQxoAAowBpF9VjrOlPSYERRJagBKdr5RTTooQYbxktcM+Yo+OUo+JG0RAH4AUW0kEGSYRT4iLJ9+xY9lohhNKEk4MoFgBU4ERMOwuCcOG0uHAYAALYAsfIQzgnUhwORyOAAeha+3R1kokWibAAgpIIHCfEVEnc4FNktlEMQCtSSncymoNDo9Jt6gZGo5nK4oSYJjtpks+IIRN1LCYbCYxC5gGg4GKpgAVZRsdwmKVmXIYfKjLV0RGymTyh7mFxubhwLw+fwiACM6OtSpgKrgAnUWl0ox1ktMInwgnwNStBPI6UgsB9fu5cFZpXuQA" rel="noopener ugc nofollow" target="_blank"><em class="nu">See this snippet on flow.org/try</em></a></p><h1 id="1490" class="nw nx gu bf ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot bk">Using higher order components (HOCs)</h1><p id="13ef" class="pw-post-body-paragraph mw mx gu my b mz ou nb nc nd ov nf ng nh ow nj nk nl ox nn no np oy nr ns nt gn bk">Higher order components are functions that take a React component and return a new React component that wraps the other component. We can use higher order components to change props that are passed down.</p><p id="e62c" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">To write HOCs, we need to use two built-in special Flow types: — the <code class="cx pi pj pk pl b">React$Component<></code> type which represents a React component instance and is parameterized with <code class="cx pi pj pk pl b">DefaultProps</code>, <code class="cx pi pj pk pl b">Props</code>, and <code class="cx pi pj pk pl b">State</code> - The <code class="cx pi pj pk pl b">Class<></code> built-in, which is parameterized with a single argument to get the class type of an instance</p><p id="2266" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">The input of an HOC is often a component class, typed as <code class="cx pi pj pk pl b">Class<React$Component<DefaultProps, Props, State>></code>, and the output is the same type, with the Props type transformed. This is best understood in an example:</p><p id="03ac" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><a class="af nv" href="https://flow.org/try/#0PTAEEsDNQTwewK6gA4EMDOAXApqTALcdCAO0zlH002XQC4RIAbOAdwDo4AnAc2Ey4xgAGliJQ6fIiYATCdlxwSTGHny4ScHHMwxkubFy7d0AKHABbZN0ygAStlQBjW5GMXQAci6OXngNymoKYy2E5MqD6gkAgkLuBKoBaoyAAKxrQAEgDyAMIAYrHxSgA8QaAAkiTICJjpcLR0oADeAL7C5QCyKfoy9Y0t7eUAItiQqAhMdRnoHaCgAMqYqDimAHwAFOXJyPkkTRvIM01VNdMN6ACUoAC8a6DdyL39ZpcHTnBWSthkTbkR6HQJQczkwABJcp9rCQfpgSqNxpNzrRRKdai9QAAyB49bB9GaiJYrbBrNbXO7lf4YIEglwQqHfMglABucHAMlR1XRBNArPZpMCwV0+lAGJuLXKHwQXHQ2AqMiaWC44BIPEFEAVEgEKrVplagtM4WpoEhXxhZFA2AAHjgSDJiLTMOxTdDYSy2RzRTy+TJ7m0gqZhbgAOpcXFcF2M5HEcXNcrsxXa1WBfUBj4kLCgUPhyPmzB-AE03zg3Nun2ibNPQylsgvUQ+0m3JIpF45ApFTAJEhbeaHGbk+4bZpSmVyzWeEey+UARk8rUupkuGxrmEuBpAYiQuQAggA5XfZAAqlqt1i4tgIIbDVYjDLzoBk4B8LhUEGg8CQrFQFvAF702AAWicdQnAAa1AD4jDCTBXxVUAtHULhonAJhsHQdhTA3AgiAgYgACMwgmWVQHyFhWFw0AIgAL1Ub85C-MhiA-PAKGtZAmHAJxf1fIMTzPTB0NAABNcROgAVQWY9IDgJgyLUHC0GoQwSEwsA4GgYUdTUK8czvWFeUicBUDw1DQDo7SSD4mwtIIFYDOVYzUIwtibAfMYJimLNr30W8zVhdcwEkaQ5E0C98GMcjDGMGVDSUTMFikSY+mNcUNgHUASkrHyVw1G4ACI8tAYA1gCiREtkNQIstIxuFAACkiIdAtPZWKM1sBLgvyVAUKbNLbnuTLvOrPSLWK-wgA" rel="noopener ugc nofollow" target="_blank"><em class="nu">See this snippet on flow.org/try</em></a></p><p id="b5c3" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">As noted in the above example, you cannot export components wrapped in HOCs directly and expect them to type-check in other files. This is because Flow is lazy and wants you to explicitly type exports. You must follow the pattern of typing the exported variable and then exporting that variable separately.</p><p id="bf5a" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk">At Coursera, we use underscore’s <a class="af nv" href="https://github.com/flowtype/flow-typed/blob/2a28851c442d50ff56a277438e7a55406b61e696/definitions/npm/underscore_v1.x.x/flow_v0.38.x-/underscore_v1.x.x.js#L10" rel="noopener ugc nofollow" target="_blank">compose function</a> (<code class="cx pi pj pk pl b">_.compose</code>) to type HOC chains. An example can be found <a class="af nv" href="https://flow.org/try/#0JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wG4AoOcgEyTQBsUi5MBXAOw2AnbhBTAAFHGADOACQDyAYQBiHLjwA8lOAEl2YVjGEQxALjgBvAL4AaVQFkBYJNV0Hj51QBEkmFK3o6Roi3DgAZRgUGCRyAD4AClV+MFl2QyiwX0MNLR89UQBKOABeCLhrMFt7X3JspLRcSHYkdhhDaUZRUSVkdBgAEmkannqYJTcPL0yxM3VNbQdROAAyIps7GYng0KQIiNyC1WaUVvbibt7wfoalADcIYGoJ9OnfCaubzYoqGABPWzgZ-ONVaqsKCiJBqaiGUQwKDAdgAczecBuEKhMPh5BMb3IDH2sxOtQGcCQAA8wuxqLMOhgAHR4s6DZ63H6POAMwqmSjkT7fADqUCWUFpdQavzy-wCSLgkOhcIoGI51XYkLgvP5goGTRabUpxz6Qvp10ZKpKSAFuoGKxZBs2fziMykcgUMG47BiAWSvm2hSiRkBwNB4IIvpBYIAjPgTNkKlE1Q1spiAPTxuAfCCsODSACCADks5IACqEomQWBwGAACyQyr5xtNpz1cGowCIGHoH0RmGTqbgAHcUA1EfAuUgALRoCtoADWcGqUGbMFbiN4EHLJpYwHoSFEVPIidLZeAswPcAARnRPCC4LJ6BBu4jZowAF5tvvUHt9mCzFNpmAQQtgejAGgwDzm2Q5-tAH5UnAACaXaWAAqoEBaYBA9DXre5ZHmAoRhFA7A7kmEAdlyqJ7pWRq2LW+L9hcTDACgx4bnAL5kbwxLFk6cJ7qELJ0QxG7buxEENu4njeFWqpmg0CZJqIZapvQr7sMue44LeJo4MCWI8EqgTyV49g4n8USenASgUSaMbwDceQAES2XA8YRDJkr6Ypqk3oSs7QHAw58AeoikTc2mKvAekKdQsgoOuxmmeZ1aUVZjnOUAA" rel="noopener ugc nofollow" target="_blank">here</a>.</p><h1 id="dbc3" class="nw nx gu bf ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot bk">Typing functions that take in component classes</h1><p id="e85f" class="pw-post-body-paragraph mw mx gu my b mz ou nb nc nd ov nf ng nh ow nj nk nl ox nn no np oy nr ns nt gn bk">There are two ways of writing React components: stateless functional components and classes. when writing higher order functions, you’ll have to deal with both cases. Here’s how a function would take both a stateless functional component and a React component class:</p><p id="5a60" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><a class="af nv" href="https://flow.org/try/#0PTAEGMEMDtQVwM4FN7QJYHtYBcCeAHJBUNAM1AHcVIAnFbSAazWgHNRbW4BbJabYhTTYAFhjjZ4CFu1FI0NUHkIIAUABMk4ADa0UpONHDZMOJkQDCGbvix9sAHgAiSUpDjbsABRoZ8CABpQHz9A0ABlBmwkAD4AClVQCGtbaHsALlALXQQEBwAlJEhjABIrGzt+Z1d3TxD-IPqwyMhomJjQAB9QOKaASlAAXg7C4uwSgFFtJF4qgCoY1T7MgDcMNHUAblVVEFAAIyRsaMVsDCl9Q2NTEn4kGmRrrBJyKlA0pHUlc7psOBpYJBkkZfvQCEgNFpdHRQAYjCZnr9-tAEOVUvZqm4PN5fA1grjmlFYgkkuAUpVsJlspBcgUiqU0RTMbUcaFGgSgi02otllkcnlRgzyWkqi4sXUOfi2REie1tpCdHpYVcEbAkQDUcKMU14olkhURZSev0hiN6eMpjMMQslplegSBsNQIKLdNZo4FpsgA" rel="noopener ugc nofollow" target="_blank"><em class="nu">See this snippet on flow.org/try</em></a></p><h1 id="de8d" class="nw nx gu bf ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot bk">Writing a higher order component</h1><p id="a9bd" class="pw-post-body-paragraph mw mx gu my b mz ou nb nc nd ov nf ng nh ow nj nk nl ox nn no np oy nr ns nt gn bk">Writing a higher order component is a bit more complex than using one. Here are some tips:</p><ul class=""><li id="a65f" class="mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt oz pa pb bk">it’s usually easier to use <a class="af nv" href="https://flow.org/en/docs/libdefs/creation/#declaring-a-module-a-classtoc-idtoc-declaring-a-module-hreftoc-declaring-a-modulea" rel="noopener ugc nofollow" target="_blank">.js.flow</a> files instead of typing the HOC file. <code class="cx pi pj pk pl b">.js.flow</code> files live next to a javascript file, and the flow file’s exports are used instead of the exports from the corresponding js file. The exports are really what matter with a higher-order component function.</li><li id="17d7" class="mw mx gu my b mz pc nb nc nd pd nf ng nh pe nj nk nl pf nn no np pg nr ns nt oz pa pb bk">HOCs should make sure to use <code class="cx pi pj pk pl b">void</code> or <code class="cx pi pj pk pl b">{}</code> for the <code class="cx pi pj pk pl b">DefaultProps</code> type, because otherwise Flow may have problems inferring Prop types.</li></ul><p id="640c" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><a class="af nv" href="https://flow.org/try/#0PQKgUABCELYIYAcAKAnA9ggzgOgFY4DMAbNAd0mgEkAXAckwgFdNG4iiBPCAUzkwEtumahGpommbhDgQCjAHYBjavzTyI-edW4pJy1ev4EIHNIwik4W0eIAm3ApqkxGRFQiJS5SlWtEcEIWwKYDAwYGBROABrIWkIACVeZQhFNBgENW5rRSI+TDB7XLgULwV9PwASeGR0LGrEVAxMAAkAeQBhADFy33kAHkgISnkERmomrAAuCABvAF8AGiGAWURA20nMGYXliAgAEQc4Vwm6zD2IAGVqOG0wAD4ACiGarvkZp4RzmZGxs+aAEoIABeB4QNYIDZbMCAz5pDJZLQzDp5TCYfpJODKSoddKZeTZaj9I4EE5uLaLYajcZbCAAMgh624m3OVJud24DwewLBQ1R+UxyWouPxSOJADc0PxbFS-rS2RApTLuQBuMIRKKxBgyYSczzo2S9AxsVJiwlaQrcYqlI0+AwQBq1ZpOrbtbrGtSDfbygHTOZLVbM1nNHbzR4vfZvD4QL4-an-La88GQ6HnWHw81Ez6+umM1MspOg8FYnEAUU8MCJ-RAPOL-LRGNLIrxiItkulsoTCuaVOVtjVYW4AA9MigRPYyadHTUtq7zu6eva1KqgA" rel="noopener ugc nofollow" target="_blank"><em class="nu">See this snippet on flow.org/try</em></a></p><h1 id="6f97" class="nw nx gu bf ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot bk">Conclusion</h1><p id="7ad2" class="pw-post-body-paragraph mw mx gu my b mz ou nb nc nd ov nf ng nh ow nj nk nl ox nn no np oy nr ns nt gn bk">As we’ve seen, using Flow and React together can be tricky for two reasons: Flow may fail to catch type errors when it should, and it may not catch type errors when they really exist. Hopefully these examples help you write modern React with the confidence that Flow offers.</p><p id="f312" class="pw-post-body-paragraph mw mx gu my b mz na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt gn bk"><em class="nu">Originally published at building.coursera.org on June 1, 2017.</em></p></div></div></div></div></section></div></div></article></div><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="pm pn ab ja"><div class="po ab"><a class="pp ay am ao" rel="noopener follow" href="/tag/react?source=post_page-----5af62a82b4df--------------------------------"><div class="pq fj cx pr ge ps pt bf b bg z bk pu">React</div></a></div><div class="po ab"><a class="pp ay am ao" rel="noopener follow" href="/tag/flow?source=post_page-----5af62a82b4df--------------------------------"><div class="pq fj cx pr ge ps pt bf b bg z bk pu">Flow</div></a></div></div></div></div><div class="l"></div><footer class="pv pw px py pz qa qb qc qd ab q qe ik c"><div class="l ae"><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="ab cp qf"><div class="ab q kv"><div class="qg l"><span class="l qh qi qj e d"><div class="ab q kv kw"><div class="pw-multi-vote-icon fj je kx ky kz"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerClapButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fcoursera-engineering%2F5af62a82b4df&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fcoursera-engineering%2Fbest-practices-for-flow-typing-react-components-5af62a82b4df&user=Coursera&userId=99c0fb464c1f&source=---footer_actions--5af62a82b4df---------------------clap_footer-----------"><div><div class="bm" aria-hidden="false"><div class="la ao lb lc ld le am lf lg lh kz"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l li lj lk ll lm ln lo"><p class="bf b dv z du"><span class="lp">--</span></p></div></div></span><span class="l h g f qk ql"><div class="ab q kv kw"><div class="pw-multi-vote-icon fj je kx ky kz"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerClapButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fcoursera-engineering%2F5af62a82b4df&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fcoursera-engineering%2Fbest-practices-for-flow-typing-react-components-5af62a82b4df&user=Coursera&userId=99c0fb464c1f&source=---footer_actions--5af62a82b4df---------------------clap_footer-----------"><div><div class="bm" aria-hidden="false"><div class="la ao lb lc ld le am lf lg lh kz"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l li lj lk ll lm ln lo"><p class="bf b dv z du"><span class="lp">--</span></p></div></div></span></div><div class="bq ab"><div><div class="bm" aria-hidden="false"><button class="ao la lq lr ab q fk ls lt" aria-label="responses"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="lu"><path d="M18.006 16.803c1.533-1.456 2.234-3.325 2.234-5.321C20.24 7.357 16.709 4 12.191 4S4 7.357 4 11.482c0 4.126 3.674 7.482 8.191 7.482.817 0 1.622-.111 2.393-.327.231.2.48.391.744.559 1.06.693 2.203 1.044 3.399 1.044.224-.008.4-.112.486-.287a.49.49 0 0 0-.042-.518c-.495-.67-.845-1.364-1.04-2.057a4 4 0 0 1-.125-.598zm-3.122 1.055-.067-.223-.315.096a8 8 0 0 1-2.311.338c-4.023 0-7.292-2.955-7.292-6.587 0-3.633 3.269-6.588 7.292-6.588 4.014 0 7.112 2.958 7.112 6.593 0 1.794-.608 3.469-2.027 4.72l-.195.168v.255c0 .056 0 .151.016.295.025.231.081.478.154.733.154.558.398 1.117.722 1.659a5.3 5.3 0 0 1-2.165-.845c-.276-.176-.714-.383-.941-.59z"></path></svg></button></div></div></div></div><div class="ab q"><div class="qm l ix"><div><div class="bm" aria-hidden="false"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerBookmarkButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fbookmark%2Fp%2F5af62a82b4df&operation=register&redirect=https%3A%2F%2Fmedium.com%2Fcoursera-engineering%2Fbest-practices-for-flow-typing-react-components-5af62a82b4df&source=---footer_actions--5af62a82b4df---------------------bookmark_footer-----------"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="none" viewBox="0 0 25 25" class="du lw" aria-label="Add to list bookmark button"><path fill="currentColor" d="M18 2.5a.5.5 0 0 1 1 0V5h2.5a.5.5 0 0 1 0 1H19v2.5a.5.5 0 1 1-1 0V6h-2.5a.5.5 0 0 1 0-1H18zM7 7a1 1 0 0 1 1-1h3.5a.5.5 0 0 0 0-1H8a2 2 0 0 0-2 2v14a.5.5 0 0 0 .805.396L12.5 17l5.695 4.396A.5.5 0 0 0 19 21v-8.5a.5.5 0 0 0-1 0v7.485l-5.195-4.012a.5.5 0 0 0-.61 0L7 19.985z"></path></svg></a></span></div></div></div><div class="qm l ix"><div class="bm" aria-hidden="false" aria-describedby="postFooterSocialMenu" aria-labelledby="postFooterSocialMenu"><div><div class="bm" aria-hidden="false"><button aria-controls="postFooterSocialMenu" aria-expanded="false" aria-label="Share Post" data-testid="footerSocialShareButton" class="af fk ah ai aj ak al me an ao ap ex mf mg lt mh"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M15.218 4.931a.4.4 0 0 1-.118.132l.012.006a.45.45 0 0 1-.292.074.5.5 0 0 1-.3-.13l-2.02-2.02v7.07c0 .28-.23.5-.5.5s-.5-.22-.5-.5v-7.04l-2 2a.45.45 0 0 1-.57.04h-.02a.4.4 0 0 1-.16-.3.4.4 0 0 1 .1-.32l2.8-2.8a.5.5 0 0 1 .7 0l2.8 2.79a.42.42 0 0 1 .068.498m-.106.138.008.004v-.01zM16 7.063h1.5a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-11c-1.1 0-2-.9-2-2v-10a2 2 0 0 1 2-2H8a.5.5 0 0 1 .35.15.5.5 0 0 1 .15.35.5.5 0 0 1-.15.35.5.5 0 0 1-.35.15H6.4c-.5 0-.9.4-.9.9v10.2a.9.9 0 0 0 .9.9h11.2c.5 0 .9-.4.9-.9v-10.2c0-.5-.4-.9-.9-.9H16a.5.5 0 0 1 0-1" clip-rule="evenodd"></path></svg></button></div></div></div></div></div></div></div></div></div></footer><div class="qn qo qp qq qr l bx"><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="qs l"><div class="ab qt qu qv iz iy"><div class="qw qx qy qz ra rb rc rd re rf ab cp"><div class="h k"><a href="https://medium.com/coursera-engineering?source=post_page---post_publication_info--5af62a82b4df--------------------------------" rel="noopener follow"><div class="fj ab"><img alt="Coursera Engineering" class="rg ib ic cx" src="https://miro.medium.com/v2/resize:fill:96:96/1*j2vLJO9qZg435iRYfd2Mfg.png" width="48" height="48" loading="lazy"/><div class="rg l ic ib fs n fr rh"></div></div></a></div><div class="j i d"><a href="https://medium.com/coursera-engineering?source=post_page---post_publication_info--5af62a82b4df--------------------------------" rel="noopener follow"><div class="fj ab"><img alt="Coursera Engineering" class="rg rj ri cx" src="https://miro.medium.com/v2/resize:fill:128:128/1*j2vLJO9qZg435iRYfd2Mfg.png" width="64" height="64" loading="lazy"/><div class="rg l ri rj fs n fr rh"></div></div></a></div><div class="j i d rk ix"><div class="ab"></div></div></div><div class="ab co rl"><div class="rm rn ro rp rq l"><a class="af ag ah aj ak al am an ao ap aq ar as at ab q" href="https://medium.com/coursera-engineering?source=post_page---post_publication_info--5af62a82b4df--------------------------------" rel="noopener follow"><h2 class="pw-author-name bf rs rt ru rv rw rx ry nh rz sa nl sb sc np sd se bk"><span class="gn rr">Published in <!-- -->Coursera Engineering</span></h2></a><div class="po ab ia"><div class="l ix"><span class="pw-follower-count bf b bg z du"><a class="af ag ah ai aj ak al am an ao ap aq ar iq" rel="noopener follow" href="/coursera-engineering/followers?source=post_page---post_publication_info--5af62a82b4df--------------------------------">3.7K Followers</a></span></div><div class="bf b bg z du ab jd"><span class="ir l" aria-hidden="true"><span class="bf b bg z du">·</span></span><a class="af ag ah ai aj ak al am an ao ap aq ar iq" rel="noopener follow" href="/coursera-engineering/two-easy-ways-to-determine-right-size-for-aws-rds-instance-through-request-mirroring-load-test-9cd6e8ac8b5c?source=post_page---post_publication_info--5af62a82b4df--------------------------------">Last published <span>Jan 3, 2023</span></a></div></div><div class="sf l"><p class="bf b bg z bk"><span class="gn">We're changing the way the world learns! Posts from Coursera engineers and data scientists.</span></p></div></div></div><div class="h k"><div class="ab"></div></div></div></div><div class="ab qt qu qv iz iy"><div class="qw qx qy qz ra rb rc rd re rf ab cp"><div class="h k"><a tabindex="0" rel="noopener follow" href="/@CourseraEng?source=post_page---post_author_info--5af62a82b4df--------------------------------"><div class="l fj"><img alt="Coursera" class="l fd by ic ib cx" src="https://miro.medium.com/v2/resize:fill:96:96/1*j2vLJO9qZg435iRYfd2Mfg.png" width="48" height="48" loading="lazy"/><div class="fr by l ic ib fs n ay rh"></div></div></a></div><div class="j i d"><a tabindex="0" rel="noopener follow" href="/@CourseraEng?source=post_page---post_author_info--5af62a82b4df--------------------------------"><div class="l fj"><img alt="Coursera" class="l fd by ri rj cx" src="https://miro.medium.com/v2/resize:fill:128:128/1*j2vLJO9qZg435iRYfd2Mfg.png" width="64" height="64" loading="lazy"/><div class="fr by l ri rj fs n ay rh"></div></div></a></div><div class="j i d rk ix"><div class="ab"><span><button class="bf b bg z sg pq sh si sj sk sl ev ew sm sn so fa fb fc fd bm fe ff">Follow</button></span></div></div></div><div class="ab co rl"><div class="rm rn ro rp rq l"><a class="af ag ah aj ak al am an ao ap aq ar as at ab q" rel="noopener follow" href="/@CourseraEng?source=post_page---post_author_info--5af62a82b4df--------------------------------"><h2 class="pw-author-name bf rs rt ru rv rw rx ry nh rz sa nl sb sc np sd se bk"><span class="gn rr">Written by <!-- -->Coursera</span></h2></a><div class="po ab ia"><div class="l ix"><span class="pw-follower-count bf b bg z du"><a class="af ag ah ai aj ak al am an ao ap aq ar iq" rel="noopener follow" href="/@CourseraEng/followers?source=post_page---post_author_info--5af62a82b4df--------------------------------">752 Followers</a></span></div><div class="bf b bg z du ab jd"><span class="ir l" aria-hidden="true"><span class="bf b bg z du">·</span></span><a class="af ag ah ai aj ak al am an ao ap aq ar iq" rel="noopener follow" href="/@CourseraEng/following?source=post_page---post_author_info--5af62a82b4df--------------------------------">1 Following</a></div></div><div class="sf l"><p class="bf b bg z bk">Providing universal access to the world’s best education. | <a class="af ag ah ai aj ak al am an ao ap aq ar nv go" href="http://www.coursera.org" rel="noopener ugc nofollow">www.coursera.org</a></p></div></div></div><div class="h k"><div class="ab"><span><button class="bf b bg z sg pq sh si sj sk sl ev ew sm sn so fa fb fc fd bm fe ff">Follow</button></span></div></div></div><div class="sp bh sq sr"></div></div></div><div class="h k j"><div class="sp bh sq ss"></div><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="st ab kv ja"><div class="su sv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://help.medium.com/hc/en-us?source=post_page-----5af62a82b4df--------------------------------" rel="noopener follow"><p class="bf b dv z du">Help</p></a></div><div class="su sv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://medium.statuspage.io/?source=post_page-----5af62a82b4df--------------------------------" rel="noopener follow"><p class="bf b dv z du">Status</p></a></div><div class="su sv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" rel="noopener follow" href="/about?autoplay=1&source=post_page-----5af62a82b4df--------------------------------"><p class="bf b dv z du">About</p></a></div><div class="su sv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" rel="noopener follow" href="/jobs-at-medium/work-at-medium-959d1a85284e?source=post_page-----5af62a82b4df--------------------------------"><p class="bf b dv z du">Careers</p></a></div><div class="su sv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="pressinquiries@medium.com?source=post_page-----5af62a82b4df--------------------------------" rel="noopener follow"><p class="bf b dv z du">Press</p></a></div><div class="su sv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://blog.medium.com/?source=post_page-----5af62a82b4df--------------------------------" rel="noopener follow"><p class="bf b dv z du">Blog</p></a></div><div class="su sv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://policy.medium.com/medium-privacy-policy-f03bf92035c9?source=post_page-----5af62a82b4df--------------------------------" rel="noopener follow"><p class="bf b dv z du">Privacy</p></a></div><div class="su sv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://policy.medium.com/medium-terms-of-service-9db0094a1e0f?source=post_page-----5af62a82b4df--------------------------------" rel="noopener follow"><p class="bf b dv z du">Terms</p></a></div><div class="su sv l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://speechify.com/medium?source=post_page-----5af62a82b4df--------------------------------" rel="noopener follow"><p class="bf b dv z du">Text to speech</p></a></div><div class="su l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" rel="noopener follow" href="/business?source=post_page-----5af62a82b4df--------------------------------"><p class="bf b dv z du">Teams</p></a></div></div></div></div></div></div></div></div></div></div><script>window.__BUILD_ID__="main-20241122-185319-7bcdc08639"</script><script>window.__GRAPHQL_URI__ = "https://medium.com/_/graphql"</script><script>window.__PRELOADED_STATE__ = {"algolia":{"queries":{}},"cache":{"experimentGroupSet":true,"reason":"","group":"enabled","tags":["group-edgeCachePosts","post-5af62a82b4df","user-99c0fb464c1f","collection-532b19e4043c"],"serverVariantState":"44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a","middlewareEnabled":true,"cacheStatus":"DYNAMIC","shouldUseCache":true,"vary":[],"lohpSummerUpsellEnabled":false,"publicationHierarchyEnabledWeb":false,"postBottomResponsesEnabled":false},"client":{"hydrated":false,"isUs":false,"isNativeMedium":false,"isSafariMobile":false,"isSafari":false,"isFirefox":false,"routingEntity":{"type":"DEFAULT","explicit":false},"viewerIsBot":false},"debug":{"requestId":"0c6fccfb-0b78-4ce1-8851-8497921e8579","hybridDevServices":[],"originalSpanCarrier":{"traceparent":"00-31e6695008a37cb8de9170d4ab840753-e0992f6cb2ee0d94-01"}},"multiVote":{"clapsPerPost":{}},"navigation":{"branch":{"show":null,"hasRendered":null,"blockedByCTA":false},"hideGoogleOneTap":false,"hasRenderedAlternateUserBanner":null,"currentLocation":"https:\u002F\u002Fmedium.com\u002Fcoursera-engineering\u002Fbest-practices-for-flow-typing-react-components-5af62a82b4df","host":"medium.com","hostname":"medium.com","referrer":"","hasSetReferrer":false,"susiModal":{"step":null,"operation":"register"},"postRead":false,"partnerProgram":{"selectedCountryCode":null},"queryString":"","currentHash":""},"config":{"nodeEnv":"production","version":"main-20241122-185319-7bcdc08639","target":"production","productName":"Medium","publicUrl":"https:\u002F\u002Fcdn-client.medium.com\u002Flite","authDomain":"medium.com","authGoogleClientId":"216296035834-k1k6qe060s2tp2a2jam4ljdcms00sttg.apps.googleusercontent.com","favicon":"production","glyphUrl":"https:\u002F\u002Fglyph.medium.com","branchKey":"key_live_ofxXr2qTrrU9NqURK8ZwEhknBxiI6KBm","algolia":{"appId":"MQ57UUUQZ2","apiKeySearch":"394474ced050e3911ae2249ecc774921","indexPrefix":"medium_","host":"-dsn.algolia.net"},"recaptchaKey":"6Lfc37IUAAAAAKGGtC6rLS13R1Hrw_BqADfS1LRk","recaptcha3Key":"6Lf8R9wUAAAAABMI_85Wb8melS7Zj6ziuf99Yot5","recaptchaEnterpriseKeyId":"6Le-uGgpAAAAAPprRaokM8AKthQ9KNGdoxaGUvVp","datadog":{"applicationId":"6702d87d-a7e0-42fe-bbcb-95b469547ea0","clientToken":"pub853ea8d17ad6821d9f8f11861d23dfed","rumToken":"pubf9cc52896502b9413b68ba36fc0c7162","context":{"deployment":{"target":"production","tag":"main-20241122-185319-7bcdc08639","commit":"7bcdc08639c179dc5172558201a3fd3abc1b5db6"}},"datacenter":"us"},"googleAnalyticsCode":"G-7JY7T788PK","googlePay":{"apiVersion":"2","apiVersionMinor":"0","merchantId":"BCR2DN6TV7EMTGBM","merchantName":"Medium","instanceMerchantId":"13685562959212738550"},"applePay":{"version":3},"signInWallCustomDomainCollectionIds":["3a8144eabfe3","336d898217ee","61061eb0c96b","138adf9c44c","819cc2aaeee0"],"mediumMastodonDomainName":"me.dm","mediumOwnedAndOperatedCollectionIds":["8a9336e5bb4","b7e45b22fec3","193b68bd4fba","8d6b8a439e32","54c98c43354d","3f6ecf56618","d944778ce714","92d2092dc598","ae2a65f35510","1285ba81cada","544c7006046e","fc8964313712","40187e704f1c","88d9857e584e","7b6769f2748b","bcc38c8f6edf","cef6983b292","cb8577c9149e","444d13b52878","713d7dbc99b0","ef8e90590e66","191186aaafa0","55760f21cdc5","9dc80918cc93","bdc4052bbdba","8ccfed20cbb2"],"tierOneDomains":["medium.com","thebolditalic.com","arcdigital.media","towardsdatascience.com","uxdesign.cc","codeburst.io","psiloveyou.xyz","writingcooperative.com","entrepreneurshandbook.co","prototypr.io","betterhumans.coach.me","theascent.pub"],"topicsToFollow":["d61cf867d93f","8a146bc21b28","1eca0103fff3","4d562ee63426","aef1078a3ef5","e15e46793f8d","6158eb913466","55f1c20aba7a","3d18b94f6858","4861fee224fd","63c6f1f93ee","1d98b3a9a871","decb52b64abf","ae5d4995e225","830cded25262"],"topicToTagMappings":{"accessibility":"accessibility","addiction":"addiction","android-development":"android-development","art":"art","artificial-intelligence":"artificial-intelligence","astrology":"astrology","basic-income":"basic-income","beauty":"beauty","biotech":"biotech","blockchain":"blockchain","books":"books","business":"business","cannabis":"cannabis","cities":"cities","climate-change":"climate-change","comics":"comics","coronavirus":"coronavirus","creativity":"creativity","cryptocurrency":"cryptocurrency","culture":"culture","cybersecurity":"cybersecurity","data-science":"data-science","design":"design","digital-life":"digital-life","disability":"disability","economy":"economy","education":"education","equality":"equality","family":"family","feminism":"feminism","fiction":"fiction","film":"film","fitness":"fitness","food":"food","freelancing":"freelancing","future":"future","gadgets":"gadgets","gaming":"gaming","gun-control":"gun-control","health":"health","history":"history","humor":"humor","immigration":"immigration","ios-development":"ios-development","javascript":"javascript","justice":"justice","language":"language","leadership":"leadership","lgbtqia":"lgbtqia","lifestyle":"lifestyle","machine-learning":"machine-learning","makers":"makers","marketing":"marketing","math":"math","media":"media","mental-health":"mental-health","mindfulness":"mindfulness","money":"money","music":"music","neuroscience":"neuroscience","nonfiction":"nonfiction","outdoors":"outdoors","parenting":"parenting","pets":"pets","philosophy":"philosophy","photography":"photography","podcasts":"podcast","poetry":"poetry","politics":"politics","privacy":"privacy","product-management":"product-management","productivity":"productivity","programming":"programming","psychedelics":"psychedelics","psychology":"psychology","race":"race","relationships":"relationships","religion":"religion","remote-work":"remote-work","san-francisco":"san-francisco","science":"science","self":"self","self-driving-cars":"self-driving-cars","sexuality":"sexuality","social-media":"social-media","society":"society","software-engineering":"software-engineering","space":"space","spirituality":"spirituality","sports":"sports","startups":"startup","style":"style","technology":"technology","transportation":"transportation","travel":"travel","true-crime":"true-crime","tv":"tv","ux":"ux","venture-capital":"venture-capital","visual-design":"visual-design","work":"work","world":"world","writing":"writing"},"defaultImages":{"avatar":{"imageId":"1*dmbNkD5D-u45r44go_cf0g.png","height":150,"width":150},"orgLogo":{"imageId":"7*V1_7XP4snlmqrc_0Njontw.png","height":110,"width":500},"postLogo":{"imageId":"bd978bb536350a710e8efb012513429cabdc4c28700604261aeda246d0f980b7","height":810,"width":1440},"postPreviewImage":{"imageId":"1*hn4v1tCaJy7cWMyb0bpNpQ.png","height":386,"width":579}},"collectionStructuredData":{"8d6b8a439e32":{"name":"Elemental","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F980\u002F1*9ygdqoKprhwuTVKUM0DLPA@2x.png","width":980,"height":159}}},"3f6ecf56618":{"name":"Forge","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F596\u002F1*uULpIlImcO5TDuBZ6lm7Lg@2x.png","width":596,"height":183}}},"ae2a65f35510":{"name":"GEN","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F264\u002F1*RdVZMdvfV3YiZTw6mX7yWA.png","width":264,"height":140}}},"88d9857e584e":{"name":"LEVEL","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*JqYMhNX6KNNb2UlqGqO2WQ.png","width":540,"height":108}}},"7b6769f2748b":{"name":"Marker","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F383\u002F1*haCUs0wF6TgOOvfoY-jEoQ@2x.png","width":383,"height":92}}},"444d13b52878":{"name":"OneZero","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*cw32fIqCbRWzwJaoQw6BUg.png","width":540,"height":123}}},"8ccfed20cbb2":{"name":"Zora","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*tZUQqRcCCZDXjjiZ4bDvgQ.png","width":540,"height":106}}}},"embeddedPostIds":{"coronavirus":"cd3010f9d81f"},"sharedCdcMessaging":{"COVID_APPLICABLE_TAG_SLUGS":[],"COVID_APPLICABLE_TOPIC_NAMES":[],"COVID_APPLICABLE_TOPIC_NAMES_FOR_TOPIC_PAGE":[],"COVID_MESSAGES":{"tierA":{"text":"For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":66,"end":73,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"tierB":{"text":"Anyone can publish on Medium per our Policies, but we don’t fact-check every story. For more info about the coronavirus, see cdc.gov.","markups":[{"start":37,"end":45,"href":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Fcategories\u002F201931128-Policies-Safety"},{"start":125,"end":132,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"paywall":{"text":"This article has been made free for everyone, thanks to Medium Members. For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":56,"end":70,"href":"https:\u002F\u002Fmedium.com\u002Fmembership"},{"start":138,"end":145,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"unbound":{"text":"This article is free for everyone, thanks to Medium Members. For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":45,"end":59,"href":"https:\u002F\u002Fmedium.com\u002Fmembership"},{"start":127,"end":134,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]}},"COVID_BANNER_POST_ID_OVERRIDE_WHITELIST":["3b31a67bff4a"]},"sharedVoteMessaging":{"TAGS":["politics","election-2020","government","us-politics","election","2020-presidential-race","trump","donald-trump","democrats","republicans","congress","republican-party","democratic-party","biden","joe-biden","maga"],"TOPICS":["politics","election"],"MESSAGE":{"text":"Find out more about the U.S. election results here.","markups":[{"start":46,"end":50,"href":"https:\u002F\u002Fcookpolitical.com\u002F2020-national-popular-vote-tracker"}]},"EXCLUDE_POSTS":["397ef29e3ca5"]},"embedPostRules":[],"recircOptions":{"v1":{"limit":3},"v2":{"limit":8}},"braintreeClientKey":"production_zjkj96jm_m56f8fqpf7ngnrd4","braintree":{"enabled":true,"merchantId":"m56f8fqpf7ngnrd4","merchantAccountId":{"usd":"AMediumCorporation_instant","eur":"amediumcorporation_EUR","cad":"amediumcorporation_CAD"},"publicKey":"ds2nn34bg2z7j5gd","braintreeEnvironment":"production","dashboardUrl":"https:\u002F\u002Fwww.braintreegateway.com\u002Fmerchants","gracePeriodDurationInDays":14,"mediumMembershipPlanId":{"monthly":"ce105f8c57a3","monthlyV2":"e8a5e126-792b-4ee6-8fba-d574c1b02fc5","monthlyWithTrial":"d5ee3dbe3db8","monthlyPremium":"fa741a9b47a2","yearly":"a40ad4a43185","yearlyV2":"3815d7d6-b8ca-4224-9b8c-182f9047866e","yearlyStaff":"d74fb811198a","yearlyWithTrial":"b3bc7350e5c7","yearlyPremium":"e21bd2c12166","monthlyOneYearFree":"e6c0637a-2bad-4171-ab4f-3c268633d83c","monthly25PercentOffFirstYear":"235ecc62-0cdb-49ae-9378-726cd21c504b","monthly20PercentOffFirstYear":"ba518864-9c13-4a99-91ca-411bf0cac756","monthly15PercentOffFirstYear":"594c029b-9f89-43d5-88f8-8173af4e070e","monthly10PercentOffFirstYear":"c6c7bc9a-40f2-4b51-8126-e28511d5bdb0","monthlyForStudents":"629ebe51-da7d-41fd-8293-34cd2f2030a8","yearlyOneYearFree":"78ba7be9-0d9f-4ece-aa3e-b54b826f2bf1","yearly25PercentOffFirstYear":"2dbb010d-bb8f-4eeb-ad5c-a08509f42d34","yearly20PercentOffFirstYear":"47565488-435b-47f8-bf93-40d5fbe0ebc8","yearly15PercentOffFirstYear":"8259809b-0881-47d9-acf7-6c001c7f720f","yearly10PercentOffFirstYear":"9dd694fb-96e1-472c-8d9e-3c868d5c1506","yearlyForStudents":"e29345ef-ab1c-4234-95c5-70e50fe6bc23","monthlyCad":"p52orjkaceei","yearlyCad":"h4q9g2up9ktt"},"braintreeDiscountId":{"oneMonthFree":"MONTHS_FREE_01","threeMonthsFree":"MONTHS_FREE_03","sixMonthsFree":"MONTHS_FREE_06","fiftyPercentOffOneYear":"FIFTY_PERCENT_OFF_ONE_YEAR"},"3DSecureVersion":"2","defaultCurrency":"usd","providerPlanIdCurrency":{"4ycw":"usd","rz3b":"usd","3kqm":"usd","jzw6":"usd","c2q2":"usd","nnsw":"usd","q8qw":"usd","d9y6":"usd","fx7w":"cad","nwf2":"cad"}},"paypalClientId":"AXj1G4fotC2GE8KzWX9mSxCH1wmPE3nJglf4Z2ig_amnhvlMVX87otaq58niAg9iuLktVNF_1WCMnN7v","paypal":{"host":"https:\u002F\u002Fapi.paypal.com:443","clientMode":"production","serverMode":"live","webhookId":"4G466076A0294510S","monthlyPlan":{"planId":"P-9WR0658853113943TMU5FDQA","name":"Medium Membership (Monthly) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"yearlyPlan":{"planId":"P-7N8963881P8875835MU5JOPQ","name":"Medium Membership (Annual) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"oneYearGift":{"name":"Medium Membership (1 Year, Digital Gift Code)","description":"Unlimited access to the best and brightest stories on Medium. Gift codes can be redeemed at medium.com\u002Fredeem.","price":"50.00","currency":"USD","sku":"membership-gift-1-yr"},"oldMonthlyPlan":{"planId":"P-96U02458LM656772MJZUVH2Y","name":"Medium Membership (Monthly)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"oldYearlyPlan":{"planId":"P-59P80963JF186412JJZU3SMI","name":"Medium Membership (Annual)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"monthlyPlanWithTrial":{"planId":"P-66C21969LR178604GJPVKUKY","name":"Medium Membership (Monthly) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"yearlyPlanWithTrial":{"planId":"P-6XW32684EX226940VKCT2MFA","name":"Medium Membership (Annual) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"oldMonthlyPlanNoSetupFee":{"planId":"P-4N046520HR188054PCJC7LJI","name":"Medium Membership (Monthly)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"oldYearlyPlanNoSetupFee":{"planId":"P-7A4913502Y5181304CJEJMXQ","name":"Medium Membership (Annual)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"sdkUrl":"https:\u002F\u002Fwww.paypal.com\u002Fsdk\u002Fjs"},"stripePublishableKey":"pk_live_7FReX44VnNIInZwrIIx6ghjl","log":{"json":true,"level":"info"},"imageUploadMaxSizeMb":25,"staffPicks":{"title":"Staff Picks","catalogId":"c7bc6e1ee00f"}},"session":{"xsrf":""}}</script><script>window.__APOLLO_STATE__ = {"ROOT_QUERY":{"__typename":"Query","viewer":null,"collectionByDomainOrSlug({\"domainOrSlug\":\"coursera-engineering\"})":{"__ref":"Collection:532b19e4043c"},"postResult({\"id\":\"5af62a82b4df\"})":{"__ref":"Post:5af62a82b4df"}},"ImageMetadata:":{"__typename":"ImageMetadata","id":"","alt":null,"focusPercentX":null,"focusPercentY":null,"originalHeight":null,"originalWidth":null},"Collection:532b19e4043c":{"__typename":"Collection","id":"532b19e4043c","favicon":{"__ref":"ImageMetadata:"},"customStyleSheet":null,"colorPalette":{"__typename":"ColorPalette","highlightSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FFFFFFFF","colorPoints":[{"__typename":"ColorPoint","color":"#FFECF3FF","point":0},{"__typename":"ColorPoint","color":"#FFE8F2FF","point":0.1},{"__typename":"ColorPoint","color":"#FFE5F0FF","point":0.2},{"__typename":"ColorPoint","color":"#FFE1EFFF","point":0.3},{"__typename":"ColorPoint","color":"#FFDDEDFF","point":0.4},{"__typename":"ColorPoint","color":"#FFD9EBFF","point":0.5},{"__typename":"ColorPoint","color":"#FFD6EAFF","point":0.6},{"__typename":"ColorPoint","color":"#FFD2E8FF","point":0.7},{"__typename":"ColorPoint","color":"#FFCEE6FF","point":0.8},{"__typename":"ColorPoint","color":"#FFCAE5FF","point":0.9},{"__typename":"ColorPoint","color":"#FFC6E3FF","point":1}]},"defaultBackgroundSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FFFFFFFF","colorPoints":[{"__typename":"ColorPoint","color":"#FF6388BF","point":0},{"__typename":"ColorPoint","color":"#FF5D7EB0","point":0.1},{"__typename":"ColorPoint","color":"#FF5775A1","point":0.2},{"__typename":"ColorPoint","color":"#FF516B91","point":0.3},{"__typename":"ColorPoint","color":"#FF4A6182","point":0.4},{"__typename":"ColorPoint","color":"#FF435673","point":0.5},{"__typename":"ColorPoint","color":"#FF3C4B63","point":0.6},{"__typename":"ColorPoint","color":"#FF334054","point":0.7},{"__typename":"ColorPoint","color":"#FF2A3444","point":0.8},{"__typename":"ColorPoint","color":"#FF202833","point":0.9},{"__typename":"ColorPoint","color":"#FF151B23","point":1}]},"tintBackgroundSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FF82A8E1","colorPoints":[{"__typename":"ColorPoint","color":"#FF82A8E1","point":0},{"__typename":"ColorPoint","color":"#FF8FB1E6","point":0.1},{"__typename":"ColorPoint","color":"#FF9CBBEA","point":0.2},{"__typename":"ColorPoint","color":"#FFA8C4EF","point":0.3},{"__typename":"ColorPoint","color":"#FFB4CDF3","point":0.4},{"__typename":"ColorPoint","color":"#FFC0D6F7","point":0.5},{"__typename":"ColorPoint","color":"#FFCCDEFB","point":0.6},{"__typename":"ColorPoint","color":"#FFD8E7FF","point":0.7},{"__typename":"ColorPoint","color":"#FFE3EFFF","point":0.8},{"__typename":"ColorPoint","color":"#FFEFF7FF","point":0.9},{"__typename":"ColorPoint","color":"#FFFAFFFF","point":1}]}},"domain":null,"slug":"coursera-engineering","googleAnalyticsId":null,"editors":[{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:d987eade03ed"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:80624ba8fd79"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:7b91bcea825"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:70814e310ce3"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:9999dd095c18"}}],"name":"Coursera Engineering","avatar":{"__ref":"ImageMetadata:1*j2vLJO9qZg435iRYfd2Mfg.png"},"description":"We're changing the way the world learns! Posts from Coursera engineers and data scientists.","subscriberCount":3778,"latestPostsConnection({\"paging\":{\"limit\":1}})":{"__typename":"PostConnection","posts":[{"__ref":"Post:9cd6e8ac8b5c"}]},"viewerEdge":{"__ref":"CollectionViewerEdge:collectionId:532b19e4043c-viewerId:lo_99369f4d2aaa"},"twitterUsername":"CourseraEng","facebookPageId":null,"logo":{"__ref":"ImageMetadata:1*zXjOKA4JKHH04Ipi2NI0jA.png"}},"User:d987eade03ed":{"__typename":"User","id":"d987eade03ed"},"User:80624ba8fd79":{"__typename":"User","id":"80624ba8fd79"},"User:7b91bcea825":{"__typename":"User","id":"7b91bcea825"},"User:70814e310ce3":{"__typename":"User","id":"70814e310ce3"},"User:9999dd095c18":{"__typename":"User","id":"9999dd095c18"},"ImageMetadata:1*j2vLJO9qZg435iRYfd2Mfg.png":{"__typename":"ImageMetadata","id":"1*j2vLJO9qZg435iRYfd2Mfg.png"},"User:dbd909ab7ead":{"__typename":"User","id":"dbd909ab7ead","customDomainState":{"__typename":"CustomDomainState","live":{"__typename":"CustomDomain","domain":"mengying-li.medium.com"}},"hasSubdomain":true,"username":"mengying-li"},"Post:9cd6e8ac8b5c":{"__typename":"Post","id":"9cd6e8ac8b5c","firstPublishedAt":1672713676343,"creator":{"__ref":"User:dbd909ab7ead"},"collection":{"__ref":"Collection:532b19e4043c"},"isSeries":false,"mediumUrl":"https:\u002F\u002Fmedium.com\u002Fcoursera-engineering\u002Ftwo-easy-ways-to-determine-right-size-for-aws-rds-instance-through-request-mirroring-load-test-9cd6e8ac8b5c","sequence":null,"uniqueSlug":"two-easy-ways-to-determine-right-size-for-aws-rds-instance-through-request-mirroring-load-test-9cd6e8ac8b5c"},"LinkedAccounts:99c0fb464c1f":{"__typename":"LinkedAccounts","mastodon":null,"id":"99c0fb464c1f"},"UserViewerEdge:userId:99c0fb464c1f-viewerId:lo_99369f4d2aaa":{"__typename":"UserViewerEdge","id":"userId:99c0fb464c1f-viewerId:lo_99369f4d2aaa","isFollowing":false,"isUser":false,"isMuting":false},"NewsletterV3:40e9ba09c284":{"__typename":"NewsletterV3","id":"40e9ba09c284","type":"NEWSLETTER_TYPE_AUTHOR","slug":"99c0fb464c1f","name":"99c0fb464c1f","collection":null,"user":{"__ref":"User:99c0fb464c1f"}},"User:99c0fb464c1f":{"__typename":"User","id":"99c0fb464c1f","name":"Coursera","username":"CourseraEng","newsletterV3":{"__ref":"NewsletterV3:40e9ba09c284"},"linkedAccounts":{"__ref":"LinkedAccounts:99c0fb464c1f"},"isSuspended":false,"imageId":"1*j2vLJO9qZg435iRYfd2Mfg.png","mediumMemberAt":0,"verifications":{"__typename":"VerifiedInfo","isBookAuthor":false},"socialStats":{"__typename":"SocialStats","followerCount":752,"followingCount":1,"collectionFollowingCount":0},"customDomainState":null,"hasSubdomain":false,"bio":"Providing universal access to the world’s best education. | www.coursera.org","isPartnerProgramEnrolled":false,"viewerEdge":{"__ref":"UserViewerEdge:userId:99c0fb464c1f-viewerId:lo_99369f4d2aaa"},"viewerIsUser":false,"postSubscribeMembershipUpsellShownAt":0,"membership":null,"allowNotes":false,"twitterScreenName":""},"Paragraph:f6541027eb41_0":{"__typename":"Paragraph","id":"f6541027eb41_0","name":"e17a","type":"H3","href":null,"layout":null,"metadata":null,"text":"Best Practices for Flow Typing React Components","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_1":{"__typename":"Paragraph","id":"f6541027eb41_1","name":"101b","type":"P","href":null,"layout":null,"metadata":null,"text":"By David Winegar","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":2,"end":16,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_2":{"__typename":"Paragraph","id":"f6541027eb41_2","name":"ecb8","type":"P","href":null,"layout":null,"metadata":null,"text":"At Coursera, we use Flow to type our Javascript and catch mistakes at compile time. Flow has been enormously useful as a documentation tool and has increased the productivity of our frontend engineers. However, this tool can be tricky to use with React; it took us several months to figure out how we could truly make our types “flow” from one component to another while still catching errors. We want to share some of our best practices with you so that you can easily type React components, stateless functional components, and higher order components (HOCs).","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":20,"end":24,"href":"https:\u002F\u002Fflow.org\u002F","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_3":{"__typename":"Paragraph","id":"f6541027eb41_3","name":"1255","type":"P","href":null,"layout":null,"metadata":null,"text":"Note that this blog post assumes passing familiarity with React and Flow. Flow works with React and JSX out of the box, but the types can sometimes be a bit tricky to deal with. For reference, you can take a look at the official Flow library definitions for React here.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":104,"end":118,"href":"https:\u002F\u002Fflow.org\u002Fen\u002Fdocs\u002Fframeworks\u002Freact\u002F","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":264,"end":268,"href":"https:\u002F\u002Fgithub.com\u002Ffacebook\u002Fflow\u002Fblob\u002Fmaster\u002Flib\u002Freact.js","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_4":{"__typename":"Paragraph","id":"f6541027eb41_4","name":"42fb","type":"H3","href":null,"layout":null,"metadata":null,"text":"Do I need to use React PropTypes if I use Flow?","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_5":{"__typename":"Paragraph","id":"f6541027eb41_5","name":"2d20","type":"P","href":null,"layout":null,"metadata":null,"text":"If you use Babel, you should strip your Flow types from your outputted code using the babel-plugin-transform-flow-strip-types. Usually both React PropTypes and Flow types are stripped out in our production builds. PropTypes provide run-time type checking in the browser console, while Flow types provide compile-time type-checking.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":86,"end":125,"href":"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fbabel-plugin-transform-flow-strip-types","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_6":{"__typename":"Paragraph","id":"f6541027eb41_6","name":"505d","type":"ULI","href":null,"layout":null,"metadata":null,"text":"If you are building a generic UI component that will be used in many places, it’s useful to add both PropTypes and Flow types so that developers see both compile-time errors and the red console PropType warnings when developing.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_7":{"__typename":"Paragraph","id":"f6541027eb41_7","name":"b9c6","type":"ULI","href":null,"layout":null,"metadata":null,"text":"If you’re building an app that uses Flow types throughout, it’s usually not necessary to also include PropTypes.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_8":{"__typename":"Paragraph","id":"f6541027eb41_8","name":"1246","type":"ULI","href":null,"layout":null,"metadata":null,"text":"If you are choosing between them, I recommend writing Flow types exclusively. They are usually more specific, easier to write, catch more errors, and can be statically analyzed for correctness without running the code.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_9":{"__typename":"Paragraph","id":"f6541027eb41_9","name":"ecc5","type":"H3","href":null,"layout":null,"metadata":null,"text":"Typing style","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_10":{"__typename":"Paragraph","id":"f6541027eb41_10","name":"0eca","type":"P","href":null,"layout":null,"metadata":null,"text":"Here are some basic style guidelines for typing React components:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_11":{"__typename":"Paragraph","id":"f6541027eb41_11","name":"3980","type":"OLI","href":null,"layout":null,"metadata":null,"text":"Prefer using React.Component\u003CDefaultProps, Props, State\u003E over props: Props; state: State; defaultProps: DefaultProps; in the function body. If DefaultProps or State are not used, use void in their place. We do this for consistency, clarity, and ease of reading the type definition for each React component.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":13,"end":56,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":62,"end":117,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":143,"end":155,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":159,"end":164,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":183,"end":187,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_12":{"__typename":"Paragraph","id":"f6541027eb41_12","name":"aa8f","type":"OLI","href":null,"layout":null,"metadata":null,"text":"Do not use * in place of DefaultProps. Using * can cause loss of type refinement because Flow expects props passed into a React component are $Diff\u003CProps, DefaultProps\u003E. This can be read as ‘at minimum, the types that are in Props that are not also in DefaultProps’. If * is used, Flow will attempt to infer a DefaultProps that fits the type definition, even if there are no DefaultProps, which results in silenced errors.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":11,"end":12,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":25,"end":37,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":45,"end":46,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":142,"end":168,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":225,"end":230,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":252,"end":264,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":270,"end":271,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":310,"end":322,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":375,"end":387,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_13":{"__typename":"Paragraph","id":"f6541027eb41_13","name":"d2a7","type":"OLI","href":null,"layout":null,"metadata":null,"text":"If you want to use React’s context, you’ll have to include contextTypes and also type context yourself, on the class body. Flow doesn’t track passing context and accepts any definition for it.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":27,"end":34,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":59,"end":71,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_14":{"__typename":"Paragraph","id":"f6541027eb41_14","name":"0785","type":"OLI","href":null,"layout":null,"metadata":null,"text":"If you want to type a function that takes a React component, use the built-in type React$Component\u003CDefaultProps, Props, State\u003E. Ex: function takeComponentClass(component: Class\u003CReact$Component\u003C*, *, *\u003E\u003E): void {};. The built-ino ReactClass type does not seem to type-check correctly.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":83,"end":126,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":132,"end":213,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":229,"end":239,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_15":{"__typename":"Paragraph","id":"f6541027eb41_15","name":"90c0","type":"OLI","href":null,"layout":null,"metadata":null,"text":"To type refs correctly, you can use Element as shown below.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":36,"end":43,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_16":{"__typename":"Paragraph","id":"f6541027eb41_16","name":"af23","type":"P","href":null,"layout":null,"metadata":null,"text":"See this snippet on flow.org\u002Ftry","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":0,"end":32,"href":"https:\u002F\u002Fflow.org\u002Ftry\u002F#0JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wG4AocmATzCTgAUcwBnOAXjgG9y45gAJgC44LGFGAA7AOYUAvhSq16AESSYUAVwA2MJhFYduvfsNHips8gso06cAMowUMepx59NLJFACSZyU0QACMfeUU0bRQWNgBhXEhJJEl4JAAPV0kBNmR0GAA6ePAIJJSAHgA3CEEAGkZmFjqqwQA+Yz40ErEoTQxoAAowBpF9VjrOlPSYERRJagBKdr5RTTooQYbxktcM+Yo+OUo+JG0RAH4AUW0kEGSYRT4iLJ9+xY9lohhNKEk4MoFgBU4ERMOwuCcOG0uHAYAALYAsfIQzgnUhwORyOAAeha+3R1kokWibAAgpIIHCfEVEnc4FNktlEMQCtSSncymoNDo9Jt6gZGo5nK4oSYJjtpks+IIRN1LCYbCYxC5gGg4GKpgAVZRsdwmKVmXIYfKjLV0RGymTyh7mFxubhwLw+fwiACM6OtSpgKrgAnUWl0ox1ktMInwgnwNStBPI6UgsB9fu5cFZpXuQA","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"EM","start":0,"end":32,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_17":{"__typename":"Paragraph","id":"f6541027eb41_17","name":"1490","type":"H3","href":null,"layout":null,"metadata":null,"text":"Using higher order components (HOCs)","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_18":{"__typename":"Paragraph","id":"f6541027eb41_18","name":"13ef","type":"P","href":null,"layout":null,"metadata":null,"text":"Higher order components are functions that take a React component and return a new React component that wraps the other component. We can use higher order components to change props that are passed down.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_19":{"__typename":"Paragraph","id":"f6541027eb41_19","name":"e62c","type":"P","href":null,"layout":null,"metadata":null,"text":"To write HOCs, we need to use two built-in special Flow types: — the React$Component\u003C\u003E type which represents a React component instance and is parameterized with DefaultProps, Props, and State - The Class\u003C\u003E built-in, which is parameterized with a single argument to get the class type of an instance","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":69,"end":86,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":162,"end":174,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":176,"end":181,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":187,"end":192,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":199,"end":206,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_20":{"__typename":"Paragraph","id":"f6541027eb41_20","name":"2266","type":"P","href":null,"layout":null,"metadata":null,"text":"The input of an HOC is often a component class, typed as Class\u003CReact$Component\u003CDefaultProps, Props, State\u003E\u003E, and the output is the same type, with the Props type transformed. This is best understood in an example:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":57,"end":107,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_21":{"__typename":"Paragraph","id":"f6541027eb41_21","name":"03ac","type":"P","href":null,"layout":null,"metadata":null,"text":"See this snippet on flow.org\u002Ftry","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":0,"end":32,"href":"https:\u002F\u002Fflow.org\u002Ftry\u002F#0PTAEEsDNQTwewK6gA4EMDOAXApqTALcdCAO0zlH002XQC4RIAbOAdwDo4AnAc2Ey4xgAGliJQ6fIiYATCdlxwSTGHny4ScHHMwxkubFy7d0AKHABbZN0ygAStlQBjW5GMXQAci6OXngNymoKYy2E5MqD6gkAgkLuBKoBaoyAAKxrQAEgDyAMIAYrHxSgA8QaAAkiTICJjpcLR0oADeAL7C5QCyKfoy9Y0t7eUAItiQqAhMdRnoHaCgAMqYqDimAHwAFOXJyPkkTRvIM01VNdMN6ACUoAC8a6DdyL39ZpcHTnBWSthkTbkR6HQJQczkwABJcp9rCQfpgSqNxpNzrRRKdai9QAAyB49bB9GaiJYrbBrNbXO7lf4YIEglwQqHfMglABucHAMlR1XRBNArPZpMCwV0+lAGJuLXKHwQXHQ2AqMiaWC44BIPEFEAVEgEKrVplagtM4WpoEhXxhZFA2AAHjgSDJiLTMOxTdDYSy2RzRTy+TJ7m0gqZhbgAOpcXFcF2M5HEcXNcrsxXa1WBfUBj4kLCgUPhyPmzB-AE03zg3Nun2ibNPQylsgvUQ+0m3JIpF45ApFTAJEhbeaHGbk+4bZpSmVyzWeEey+UARk8rUupkuGxrmEuBpAYiQuQAggA5XfZAAqlqt1i4tgIIbDVYjDLzoBk4B8LhUEGg8CQrFQFvAF702AAWicdQnAAa1AD4jDCTBXxVUAtHULhonAJhsHQdhTA3AgiAgYgACMwgmWVQHyFhWFw0AIgAL1Ub85C-MhiA-PAKGtZAmHAJxf1fIMTzPTB0NAABNcROgAVQWY9IDgJgyLUHC0GoQwSEwsA4GgYUdTUK8czvWFeUicBUDw1DQDo7SSD4mwtIIFYDOVYzUIwtibAfMYJimLNr30W8zVhdcwEkaQ5E0C98GMcjDGMGVDSUTMFikSY+mNcUNgHUASkrHyVw1G4ACI8tAYA1gCiREtkNQIstIxuFAACkiIdAtPZWKM1sBLgvyVAUKbNLbnuTLvOrPSLWK-wgA","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"EM","start":0,"end":32,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_22":{"__typename":"Paragraph","id":"f6541027eb41_22","name":"b5c3","type":"P","href":null,"layout":null,"metadata":null,"text":"As noted in the above example, you cannot export components wrapped in HOCs directly and expect them to type-check in other files. This is because Flow is lazy and wants you to explicitly type exports. You must follow the pattern of typing the exported variable and then exporting that variable separately.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_23":{"__typename":"Paragraph","id":"f6541027eb41_23","name":"bf5a","type":"P","href":null,"layout":null,"metadata":null,"text":"At Coursera, we use underscore’s compose function (_.compose) to type HOC chains. An example can be found here.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":51,"end":60,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":33,"end":49,"href":"https:\u002F\u002Fgithub.com\u002Fflowtype\u002Fflow-typed\u002Fblob\u002F2a28851c442d50ff56a277438e7a55406b61e696\u002Fdefinitions\u002Fnpm\u002Funderscore_v1.x.x\u002Fflow_v0.38.x-\u002Funderscore_v1.x.x.js#L10","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":106,"end":110,"href":"https:\u002F\u002Fflow.org\u002Ftry\u002F#0JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wG4AoOcgEyTQBsUi5MBXAOw2AnbhBTAAFHGADOACQDyAYQBiHLjwA8lOAEl2YVjGEQxALjgBvAL4AaVQFkBYJNV0Hj51QBEkmFK3o6Roi3DgAZRgUGCRyAD4AClV+MFl2QyiwX0MNLR89UQBKOABeCLhrMFt7X3JspLRcSHYkdhhDaUZRUSVkdBgAEmkannqYJTcPL0yxM3VNbQdROAAyIps7GYng0KQIiNyC1WaUVvbibt7wfoalADcIYGoJ9OnfCaubzYoqGABPWzgZ-ONVaqsKCiJBqaiGUQwKDAdgAczecBuEKhMPh5BMb3IDH2sxOtQGcCQAA8wuxqLMOhgAHR4s6DZ63H6POAMwqmSjkT7fADqUCWUFpdQavzy-wCSLgkOhcIoGI51XYkLgvP5goGTRabUpxz6Qvp10ZKpKSAFuoGKxZBs2fziMykcgUMG47BiAWSvm2hSiRkBwNB4IIvpBYIAjPgTNkKlE1Q1spiAPTxuAfCCsODSACCADks5IACqEomQWBwGAACyQyr5xtNpz1cGowCIGHoH0RmGTqbgAHcUA1EfAuUgALRoCtoADWcGqUGbMFbiN4EHLJpYwHoSFEVPIidLZeAswPcAARnRPCC4LJ6BBu4jZowAF5tvvUHt9mCzFNpmAQQtgejAGgwDzm2Q5-tAH5UnAACaXaWAAqoEBaYBA9DXre5ZHmAoRhFA7A7kmEAdlyqJ7pWRq2LW+L9hcTDACgx4bnAL5kbwxLFk6cJ7qELJ0QxG7buxEENu4njeFWqpmg0CZJqIZapvQr7sMue44LeJo4MCWI8EqgTyV49g4n8USenASgUSaMbwDceQAES2XA8YRDJkr6Ypqk3oSs7QHAw58AeoikTc2mKvAekKdQsgoOuxmmeZ1aUVZjnOUAA","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_24":{"__typename":"Paragraph","id":"f6541027eb41_24","name":"dbc3","type":"H3","href":null,"layout":null,"metadata":null,"text":"Typing functions that take in component classes","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_25":{"__typename":"Paragraph","id":"f6541027eb41_25","name":"e85f","type":"P","href":null,"layout":null,"metadata":null,"text":"There are two ways of writing React components: stateless functional components and classes. when writing higher order functions, you’ll have to deal with both cases. Here’s how a function would take both a stateless functional component and a React component class:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_26":{"__typename":"Paragraph","id":"f6541027eb41_26","name":"5a60","type":"P","href":null,"layout":null,"metadata":null,"text":"See this snippet on flow.org\u002Ftry","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":0,"end":32,"href":"https:\u002F\u002Fflow.org\u002Ftry\u002F#0PTAEGMEMDtQVwM4FN7QJYHtYBcCeAHJBUNAM1AHcVIAnFbSAazWgHNRbW4BbJabYhTTYAFhjjZ4CFu1FI0NUHkIIAUABMk4ADa0UpONHDZMOJkQDCGbvix9sAHgAiSUpDjbsABRoZ8CABpQHz9A0ABlBmwkAD4AClVQCGtbaHsALlALXQQEBwAlJEhjABIrGzt+Z1d3TxD-IPqwyMhomJjQAB9QOKaASlAAXg7C4uwSgFFtJF4qgCoY1T7MgDcMNHUAblVVEFAAIyRsaMVsDCl9Q2NTEn4kGmRrrBJyKlA0pHUlc7psOBpYJBkkZfvQCEgNFpdHRQAYjCZnr9-tAEOVUvZqm4PN5fA1grjmlFYgkkuAUpVsJlspBcgUiqU0RTMbUcaFGgSgi02otllkcnlRgzyWkqi4sXUOfi2REie1tpCdHpYVcEbAkQDUcKMU14olkhURZSev0hiN6eMpjMMQslplegSBsNQIKLdNZo4FpsgA","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"EM","start":0,"end":32,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_27":{"__typename":"Paragraph","id":"f6541027eb41_27","name":"de8d","type":"H3","href":null,"layout":null,"metadata":null,"text":"Writing a higher order component","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_28":{"__typename":"Paragraph","id":"f6541027eb41_28","name":"a9bd","type":"P","href":null,"layout":null,"metadata":null,"text":"Writing a higher order component is a bit more complex than using one. Here are some tips:","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_29":{"__typename":"Paragraph","id":"f6541027eb41_29","name":"a65f","type":"ULI","href":null,"layout":null,"metadata":null,"text":"it’s usually easier to use .js.flow files instead of typing the HOC file. .js.flow files live next to a javascript file, and the flow file’s exports are used instead of the exports from the corresponding js file. The exports are really what matter with a higher-order component function.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":74,"end":82,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":27,"end":35,"href":"https:\u002F\u002Fflow.org\u002Fen\u002Fdocs\u002Flibdefs\u002Fcreation\u002F#declaring-a-module-a-classtoc-idtoc-declaring-a-module-hreftoc-declaring-a-modulea","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_30":{"__typename":"Paragraph","id":"f6541027eb41_30","name":"17d7","type":"ULI","href":null,"layout":null,"metadata":null,"text":"HOCs should make sure to use void or {} for the DefaultProps type, because otherwise Flow may have problems inferring Prop types.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":29,"end":33,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":37,"end":39,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":48,"end":60,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_31":{"__typename":"Paragraph","id":"f6541027eb41_31","name":"640c","type":"P","href":null,"layout":null,"metadata":null,"text":"See this snippet on flow.org\u002Ftry","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":0,"end":32,"href":"https:\u002F\u002Fflow.org\u002Ftry\u002F#0PQKgUABCELYIYAcAKAnA9ggzgOgFY4DMAbNAd0mgEkAXAckwgFdNG4iiBPCAUzkwEtumahGpommbhDgQCjAHYBjavzTyI-edW4pJy1ev4EIHNIwik4W0eIAm3ApqkxGRFQiJS5SlWtEcEIWwKYDAwYGBROABrIWkIACVeZQhFNBgENW5rRSI+TDB7XLgULwV9PwASeGR0LGrEVAxMAAkAeQBhADFy33kAHkgISnkERmomrAAuCABvAF8AGiGAWURA20nMGYXliAgAEQc4Vwm6zD2IAGVqOG0wAD4ACiGarvkZp4RzmZGxs+aAEoIABeB4QNYIDZbMCAz5pDJZLQzDp5TCYfpJODKSoddKZeTZaj9I4EE5uLaLYajcZbCAAMgh624m3OVJud24DwewLBQ1R+UxyWouPxSOJADc0PxbFS-rS2RApTLuQBuMIRKKxBgyYSczzo2S9AxsVJiwlaQrcYqlI0+AwQBq1ZpOrbtbrGtSDfbygHTOZLVbM1nNHbzR4vfZvD4QL4-an-La88GQ6HnWHw81Ez6+umM1MspOg8FYnEAUU8MCJ-RAPOL-LRGNLIrxiItkulsoTCuaVOVtjVYW4AA9MigRPYyadHTUtq7zu6eva1KqgA","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"EM","start":0,"end":32,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_32":{"__typename":"Paragraph","id":"f6541027eb41_32","name":"6f97","type":"H3","href":null,"layout":null,"metadata":null,"text":"Conclusion","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_33":{"__typename":"Paragraph","id":"f6541027eb41_33","name":"7ad2","type":"P","href":null,"layout":null,"metadata":null,"text":"As we’ve seen, using Flow and React together can be tricky for two reasons: Flow may fail to catch type errors when it should, and it may not catch type errors when they really exist. Hopefully these examples help you write modern React with the confidence that Flow offers.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:f6541027eb41_34":{"__typename":"Paragraph","id":"f6541027eb41_34","name":"f312","type":"P","href":null,"layout":null,"metadata":null,"text":"Originally published at building.coursera.org on June 1, 2017.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":0,"end":62,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"CollectionViewerEdge:collectionId:532b19e4043c-viewerId:lo_99369f4d2aaa":{"__typename":"CollectionViewerEdge","id":"collectionId:532b19e4043c-viewerId:lo_99369f4d2aaa","isEditor":false,"isMuting":false},"ImageMetadata:1*zXjOKA4JKHH04Ipi2NI0jA.png":{"__typename":"ImageMetadata","id":"1*zXjOKA4JKHH04Ipi2NI0jA.png","originalWidth":1156,"originalHeight":164},"PostViewerEdge:postId:5af62a82b4df-viewerId:lo_99369f4d2aaa":{"__typename":"PostViewerEdge","shouldIndexPostForExternalSearch":true,"id":"postId:5af62a82b4df-viewerId:lo_99369f4d2aaa"},"Tag:react":{"__typename":"Tag","id":"react","displayTitle":"React","normalizedTagSlug":"react"},"Tag:flow":{"__typename":"Tag","id":"flow","displayTitle":"Flow","normalizedTagSlug":"flow"},"Post:5af62a82b4df":{"__typename":"Post","id":"5af62a82b4df","collection":{"__ref":"Collection:532b19e4043c"},"content({\"postMeteringOptions\":{}})":{"__typename":"PostContent","isLockedPreviewOnly":false,"bodyModel":{"__typename":"RichText","sections":[{"__typename":"Section","name":"e763","startIndex":0,"textLayout":null,"imageLayout":null,"backgroundImage":null,"videoLayout":null,"backgroundVideo":null}],"paragraphs":[{"__ref":"Paragraph:f6541027eb41_0"},{"__ref":"Paragraph:f6541027eb41_1"},{"__ref":"Paragraph:f6541027eb41_2"},{"__ref":"Paragraph:f6541027eb41_3"},{"__ref":"Paragraph:f6541027eb41_4"},{"__ref":"Paragraph:f6541027eb41_5"},{"__ref":"Paragraph:f6541027eb41_6"},{"__ref":"Paragraph:f6541027eb41_7"},{"__ref":"Paragraph:f6541027eb41_8"},{"__ref":"Paragraph:f6541027eb41_9"},{"__ref":"Paragraph:f6541027eb41_10"},{"__ref":"Paragraph:f6541027eb41_11"},{"__ref":"Paragraph:f6541027eb41_12"},{"__ref":"Paragraph:f6541027eb41_13"},{"__ref":"Paragraph:f6541027eb41_14"},{"__ref":"Paragraph:f6541027eb41_15"},{"__ref":"Paragraph:f6541027eb41_16"},{"__ref":"Paragraph:f6541027eb41_17"},{"__ref":"Paragraph:f6541027eb41_18"},{"__ref":"Paragraph:f6541027eb41_19"},{"__ref":"Paragraph:f6541027eb41_20"},{"__ref":"Paragraph:f6541027eb41_21"},{"__ref":"Paragraph:f6541027eb41_22"},{"__ref":"Paragraph:f6541027eb41_23"},{"__ref":"Paragraph:f6541027eb41_24"},{"__ref":"Paragraph:f6541027eb41_25"},{"__ref":"Paragraph:f6541027eb41_26"},{"__ref":"Paragraph:f6541027eb41_27"},{"__ref":"Paragraph:f6541027eb41_28"},{"__ref":"Paragraph:f6541027eb41_29"},{"__ref":"Paragraph:f6541027eb41_30"},{"__ref":"Paragraph:f6541027eb41_31"},{"__ref":"Paragraph:f6541027eb41_32"},{"__ref":"Paragraph:f6541027eb41_33"},{"__ref":"Paragraph:f6541027eb41_34"}]},"validatedShareKey":"","shareKeyCreator":null},"creator":{"__ref":"User:99c0fb464c1f"},"inResponseToEntityType":null,"isLocked":false,"isMarkedPaywallOnly":false,"lockedSource":"LOCKED_POST_SOURCE_NONE","mediumUrl":"https:\u002F\u002Fmedium.com\u002Fcoursera-engineering\u002Fbest-practices-for-flow-typing-react-components-5af62a82b4df","primaryTopic":null,"topics":[{"__typename":"Topic","slug":"javascript"}],"isPublished":true,"latestPublishedVersion":"f6541027eb41","visibility":"PUBLIC","postResponses":{"__typename":"PostResponses","count":0},"clapCount":28,"allowResponses":true,"isLimitedState":false,"title":"Best Practices for Flow Typing React Components","isSeries":false,"sequence":null,"uniqueSlug":"best-practices-for-flow-typing-react-components-5af62a82b4df","socialTitle":"","socialDek":"","canonicalUrl":"","metaDescription":"","latestPublishedAt":1524768503322,"readingTime":3.539622641509434,"previewContent":{"__typename":"PreviewContent","subtitle":"By David Winegar"},"previewImage":{"__ref":"ImageMetadata:"},"isShortform":false,"seoTitle":"","firstPublishedAt":1496275200000,"updatedAt":1528828371304,"shortformType":"SHORTFORM_TYPE_LINK","seoDescription":"","viewerEdge":{"__ref":"PostViewerEdge:postId:5af62a82b4df-viewerId:lo_99369f4d2aaa"},"isSuspended":false,"license":"ALL_RIGHTS_RESERVED","tags":[{"__ref":"Tag:react"},{"__ref":"Tag:flow"}],"isNewsletter":false,"statusForCollection":"APPROVED","pendingCollection":null,"detectedLanguage":"en","wordCount":938,"layerCake":0,"responsesLocked":false}}</script><script>window.__MIDDLEWARE_STATE__={"session":{"xsrf":""},"cache":{"cacheStatus":"MISS"}}</script><script src="https://cdn-client.medium.com/lite/static/js/manifest.b2314f6d.js"></script><script src="https://cdn-client.medium.com/lite/static/js/9865.1496d74a.js"></script><script src="https://cdn-client.medium.com/lite/static/js/main.24534aeb.js"></script><script src="https://cdn-client.medium.com/lite/static/js/instrumentation.d9108df7.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/reporting.ff22a7a5.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/9120.5df29668.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5049.d1ead72d.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/4810.6318add7.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6618.db187378.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2707.b0942613.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/9977.5b3eb23a.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8599.1ab63137.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5250.9f9e01d2.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6349.b071a958.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2648.26563adf.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8393.826a25fb.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7079.67349d50.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/3735.afb7e926.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5642.a2d9f6a1.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6546.cd03f950.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6834.08de95de.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7346.72622eb9.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2420.2a5e2d95.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/839.ca7937c2.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7975.d195c6f1.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2106.21ff89d3.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7394.3d049572.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2961.00a48598.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8204.c4082863.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/4391.59acaed3.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/PostPage.MainContent.c8a11795.chunk.js"></script><script>window.main();</script><script>(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'8e735cfaf863ce87',t:'MTczMjM4ODAxOS4wMDAwMDA='};var a=document.createElement('script');a.nonce='';a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script></body></html>