Advanced
Component
Patterns

siddharthkp

I teach React

MUST LEARN ALL PATTERNS

7 component patterns

DESIGN DEVELOPMENT

const TextInput

props =>

{ return

( < input className =" input " type =" text " placeholder ={ props . placeholder } /> ) } render ( < TextInput placeholder =" Enter

some

text"

/> )

const TextInput

props =>

{ return

( < input className =" input " type =" text " placeholder ={ props . placeholder } /> ) } render ( < TextInput placeholder =" Enter

some

text"

/> )

const TextInput

props =>

{ return

( < input className =" input " type =" text " placeholder ={ props . placeholder } /> ) } render ( < TextInput readOnly placeholder =" Enter

some

text"

/> )

const TextInput

props =>

{ let classes

'input' if

( props . readOnly ) classes +=

' readonly' return

( < input className ={ classes } type =" text " placeholder ={ props . placeholder } /> ) } render ( < TextInput readOnly placeholder =" Enter

some

text"

/> )

const TextInput

props =>

{ let classes

'input' if

( props . readOnly ) classes +=

' readonly' return

( < input className ={ classes } type =" text " placeholder ={ props . placeholder } readOnly ={ props . readOnly } /> ) } render ( < TextInput readOnly placeholder =" Enter

some

text"

/> )

Functional component

const TextInput

props =>

{ let classes

'input' if

( props . readOnly ) classes +=

' readonly' return

( < input className ={ classes } type =" text " placeholder ={ props . placeholder } readOnly ={ props . readOnly } /> ) } render ( < TextInput readOnly placeholder =" Enter

some

text"

/> )

0 chars

const TextInput

props =>

{ return

( < input className =" input " type =" text " placeholder ={ props . placeholder } /> ) } 0 chars

const TextInput

props =>

{ return

( < div

< span

0 chars </ span

< input className =" input " type =" text " placeholder ={ props . placeholder } /> </ div

) } 0 chars

class TextInput extends React . Component { render ()

{ return

( < div

< span

0 chars </ span

< input className =" input " type =" text " placeholder ={ props . placeholder } /> </ div

) } } 0 chars

class TextInput extends React . Component { render ()

{ return

( < div

< span

0 chars </ span

< input className =" input " type =" text " placeholder ={ this . props . placeholder } /> </ div

) } } 0 chars

class TextInput extends React . Component { constructor (props)

{ super (props) this . state

{ length :

0

} } render ()

{ return

( < div

< span

0 chars </ span

< input className =" input " type =" text " placeholder ={ this . props . placeholder } /> </ div

) } } 0 chars

class TextInput extends React . Component { constructor (props)

{ super (props) this . state

{ length :

0

} } render ()

{ return

( < div

< span

{ this . state . length } chars </ span

< input className =" input " type =" text " placeholder ={ this . props . placeholder } /> </ div

) } } 0 chars

class TextInput extends React . Component { constructor (props)

{ ... } render ()

{ return

( < div

< span

{ this . state . length } chars </ span

< input className =" input " type =" text " placeholder ={ this . props . placeholder } /> </ div

) } } 0 chars

class TextInput extends React . Component { constructor (props)

{ ... } onChange ( event )

{ this . setState ({ length : event . target . value . length }) } render ()

{ return

( < div

< span

{ this . state . length } chars </ span

< input className =" input " type =" text " placeholder ={ this . props . placeholder } /> </ div

) } } 0 chars

class TextInput extends React . Component { constructor (props)

{ ... } onChange ( event )

{ this . setState ({ length : event . target . value . length }) } render ()

{ return

( < div

< span

{ this . state . length } chars </ span

< input className =" input " type =" text " placeholder ={ this . props . placeholder

onChange ={ this . onChange . bind ( this )} /> </ div

) } 0 chars Abc 3 chars

Class component

class TextInput extends React . Component { constructor (props)

{ ... } onChange ( event )

{ this . setState ({ length : event . target . value . length }) } render ()

{ return

( < div

< span

{ this . state . length } chars </ span

< input className =" input " type =" text " placeholder ={ this . props . placeholder

onChange ={ this . onChange . bind ( this )} /> </ div

) } 0 chars Abc 3 chars

class TextInput extends React . Component { constructor (props)

{ ... } onChange ( event )

{ this . setState ({ length : event . target . value . length }) } render ()

{ return

( < div

< span

{ this . state . length } chars </ span

< input className =" input " type =" text " placeholder ={ this . props . placeholder

onChange ={ this . onChange . bind ( this )} /> </ div

) } 0 chars Abc 3 chars

class TextInput extends React . Component { constructor (props)

{ ... } onChange ( event )

{ this . setState ({ length : event . target . value . length }) } render ()

{ return

( < div

< span

{ this . state . length } chars </ span

< input className =" input " type =" text " placeholder ={ this . props . placeholder

onChange ={ this . onChange } /> </ div

) } 0 chars Abc 3 chars

class TextInput extends React . Component { constructor (props)

{ ... } onChange

( event )

=> { this . setState ({ length : event . target . value . length }) } render ()

{ return

( < div

< span

{ this . state . length } chars </ span

< input className =" input " type =" text " placeholder ={ this . props . placeholder

onChange ={ this . onChange } /> </ div

) } 0 chars Abc 3 chars

class TextInput extends React . Component { constructor (props)

{ ... } onChange

( event )

=> { ... }
render ()

{ return

( < div

< span

{ this . state . length } chars </ span

< input className =" input " type =" text " placeholder ={ this . props . placeholder

onChange ={ this . onChange } /> </ div

) 0 chars Abc 3 chars

class TextInput extends React . Component { constructor (props)

{ super (props) this . state

{ length :

0

} } onChange

( event )

=> { ... }
render ()

{ return

( < div

< span

{ this . state . length } chars </ span

< input className =" input " type =" text " placeholder ={ this . props . placeholder

onChange ={ this . onChange } /> </ div

) 0 chars Abc 3 chars

class TextInput extends React . Component { state

{ length :

0

} onChange

( event )

=> { ... }
render ()

{ return

( < div

< span

{ this . state . length } chars </ span

< input className =" input " type =" text " placeholder ={ this . props . placeholder

onChange ={ this . onChange } /> </ div

) 0 chars Abc 3 chars

class TextInput extends React . Component { state

{ length :

0

} onChange

( event )

=> { ... }
render ()

{ return

( < div

< span

{ this . state . length } chars </ span

< input className =" input " type =" text " placeholder ={ this . props . placeholder

onChange ={ this . onChange } /> </ div

) } } 0 chars Abc 3 chars

1/3

class TextInput extends React . Component { state

{ length :

0

} onChange

( event )

=> { ... }
render ()

{ return

( < div

< span

{ this . state . length } chars </ span

< input className =" input " type =" text " placeholder ={ this . props . placeholder

onChange ={ this . onChange } /> </ div

) } } 0 chars Abc 3 chars

0 chars email Siddharth@Gmail.Com siddharth@gmail.com

class TextInput extends React . Component { render ()

{ return

( < input type =" text " placeholder ={ this . props . placeholder } /> ) } } email

Un controlled component

class TextInput extends React . Component { render ()

{ return

( < input type =" text " placeholder ={ this . props . placeholder } /> ) } } email SIDDHARTH

class TextInput extends React . Component { state

{ value :

''

} render ()

{ return

( < input value ={ this . state . value } type =" text " placeholder ={ this . props . placeholder } /> ) } } email

class TextInput extends React . Component { state

{ value :

''

} render ()

{ return

( < input value ={ this . state . value } type =" text " placeholder ={ this . props . placeholder } /> ) } } email s

class TextInput extends React . Component { state

{ value :

''

} render ()

{ return

( < input value ={ this . state . value } type =" text " placeholder ={ this . props . placeholder } /> ) } } email s

class TextInput extends React . Component { state

{ value :

''

} onChange

( event )

=> {

this . setState ({ value : event . target . value . toLowerCase ()

}) } render ()

{ return

( < input onChange ={ this . onChange } value ={ this . state . value } type =" text " placeholder ={ this . props . placeholder } /> ) } } email

class TextInput extends React . Component { state

{ value :

''

} onChange

( event )

=> {

this . setState ({ value : event . target . value . toLowerCase ()

}) } render ()

{ return

( < input onChange ={ this . onChange } value ={ this . state . value } type =" text " placeholder ={ this . props . placeholder } /> ) } } email siddharth@gmail.com SIDDHARTH@Gmail.com

0 chars email siddharth@gmail.com address

render ( < TextArea placeholder =" Enter

some

text"

/> ) address

render ( withLabel ( ‘address' , < TextArea placeholder =" Enter

some

text"

/>) ) address

const withLabel

( label , Component )

=>

{ } render ( withLabel ( ‘address' , < TextArea placeholder =" Enter

some

text"

/>) ) address

const withLabel

( label , Component )

=>

{ return

( < div className =" form-field "> < label

{ label }</ label

< Component /> </ div

) } render ( withLabel ( ‘address' , < TextArea placeholder =" Enter

some

text"

/>) ) address

Higher Order Component

const withLabel

( label , Component )

=>

{ return

( < div className =" form-field "> < label

{ label }</ label

< Component /> </ div

) } render ( withLabel ( ‘address' , < TextArea placeholder =" Enter

some

text"

/>) ) address

const withLabel

( label , Component )

=>

{ return

( < div className =" form-field "> < label

{ label }</ label

< Component /> </ div

) } render ( < WithLabel label =" address "> < TextArea placeholder =" Enter

some

text"

/> </ WithLabel

) address

const WithLabel

( props )

=>

{ return

( < div className =" form-field "> < label

{ label }</ label

< Component /> </ div

) } render ( < WithLabel label =" address "> < TextArea placeholder =" Enter

some

text"

/> </ WithLabel

) address

const withLabel

( props )

=>

{ return

( < div className =" form-field "> < label

{ label }</ label

{ props.children } </ div

) } render ( < WithLabel label =" address "> < TextArea placeholder =" Enter

some

text"

/> </ WithLabel

) address

address accept? email

render ( < form

</ form

) email

render ( < form

< WithLabel label =" address "> < TextInput placeholder =" Enter

some

text"

/> </ WithLabel

</ form

) email

render ( < form

< WithLabel label =" address "> < TextInput placeholder =" Enter

some

text"

/> </ WithLabel

< WithLabel label =" address "> < TextArea

placeholder =" Enter

some

text"

/> </ WithLabel

< WithLabel label =" accept? "> < Switch

/> </ WithLabel

</ form

) email

render ( < form

< WithLabel label =" address "> < TextInput placeholder =" Enter

some

text"

/> </ WithLabel

< WithLabel label =" address "> < TextArea

placeholder =" Enter

some

text"

/> </ WithLabel

< WithLabel label =" accept? "> < Switch

/> </ WithLabel

< div className =" actions "> < Button

primary

onClick ={ this . save }>Save</ Button

< Button

onClick ={ this . clear }>Clear</ Button

</ div

</ form

) email

address accept? email

render ( < form

< WithLabel label =" address "> < TextInput placeholder =" Enter

some

text"

/> </ WithLabel

< WithLabel label =" address "> < Form.TextArea placeholder =" Enter

some

text"

/> </ WithLabel

< WithLabel label =“ accept? "> < Form.Switch /> </ WithLabel

< div className =" actions "> < Button

primary

onClick ={ this . save }>Save</ Button

< Button

onClick ={ this . clear }>Clear</ Button

</ div

</ form

) email

render ( < Form

< Form.TextInput label =" email "

placeholder =" Enter

some

text"

/> < Form.TextArea label =" address "

placeholder =" Enter

some

text"

/> < Form.Switch label =" accept? " /> < Form. Actions primary ={{ label :

'Save Changes' , method : this.save }} secondary ={{ label :

'Save Changes' ,

method : this.save }} /> </ Form

) email

Compound Component ❤

compo 
 compo

render ( < Form

< Form.TextInput label =" email "

placeholder =" Enter

some

text"

/> < Form.TextArea label =" address "

placeholder =" Enter

some

text"

/> < Form.Switch label =" accept? " /> < Form. Actions primary ={{ label :

'Save Changes' , method : this.save }} secondary ={{ label :

'Save Changes' ,

method : this.save }} /> </ Form

) email

< Form

< Form.TextInput label =" email "

placeholder =" Enter

some

text"

/> < Form.TextArea label =" address "

placeholder =" Enter

some

text"

/> email

const Form

( props )

=>

{ return

(< form

{ props.children }</ form ) } < Form.TextInput label =" email "

placeholder =" Enter

some

text"

/> < Form.TextArea label =" address "

placeholder =" Enter

some

text"

/> email

const Form

( props )

=>

{ return

(< form

{ props.children }</ form ) } Form . TextInput = props =>

{ return

( < WithLabel

label ={ props.label }> < TextInput placeholder ={ props.placeholder }

/> </ WithLabel

) } < Form.TextArea label =" address "

placeholder =" Enter

some

text"

/> email

const Form

( props )

=>

{ return

(< form

{ props.children }</ form ) } Form . TextInput = props =>

{ return

( < WithLabel

label ={ props.label }> < TextInput placeholder ={ props.placeholder }

/> </ WithLabel

) } Form . TextArea

props =>

{ return

( < WithLabel

label ={ props.label }> < TextArea placeholder ={ props.placeholder }

/> </ WithLabel

) email

render ( < Form

< Form.TextInput label =" email "

placeholder =" Enter

some

text"

/> < Form.TextArea label =" address "

placeholder =" Enter

some

text"

/> < Form.Switch label =" accept? " /> < Form. Actions primary ={{ label :

'Save Changes' , method : this.save }} secondary ={{ label :

'Save Changes' ,

method : this.save }} /> </ Form

) email

email address accept?

render ( < Form

< Form.TextInput label =" email "

placeholder =" Enter

some

text"

/> < Form.TextArea label =" address "

placeholder =" Enter

some

text"

/> < Form.Switch label =" accept? " /> < Form. Actions primary ={{ label :

'Save Changes' , method : this.save }} secondary ={{ label :

'Save Changes' ,

method : this.save }} /> </ Form

) email

email address accept?

email address accept?

0 chars

0 chars PROJECT NAME Abc really long name, omg goes on and on 34 chars

0 chars PROJECT NAME Abc really long name, omg goes on and on 34 chars class TextInput extends React . Component { constructor (props)

{ ... } onChange ( event )

{ this . setState ({ length : event . target . value . length }) } render ()

{ return

( < div

< input onChange ={ this . onChange . bind ( this ) /> < span

{ this . state . length } chars </ span

</ div

) } }

0 chars PROJECT NAME Abc really long name, omg goes on and on 34 chars class TextInput extends React . Component { constructor (props)

{ ... } onChange ( event )

{ const error

event . target . value . length

30 this . setState ({ length : event . target . value . length, error }) } render ()

{ return

( < div

< input onChange ={ this . onChange . bind ( this ) /> < span className ={...}>{ this . state . length } chars </ span

</ div

) } }

0 chars PROJECT NAME Abc really long name, omg goes on and on 34 chars class TextInput extends React . Component { constructor (props)

{ ... } onChange ( event )

{ const error

event . target . value . length

this . props.limit this . setState ({ length : event . target . value . length, error }) } render ()

{ return

( < div

< input onChange ={ this . onChange . bind ( this ) /> < span className ={...}>{ this . state . length } chars </ span

</ div

) } }

0 chars PROJECT NAME Abc really long name, omg goes on and on 34 chars class TextInput extends React . Component { ... } render (< TextInput limit ={ 30 }

/>)

0 chars PROJECT NAME Abc really long name, omg goes on and on 34 chars 0 chars Abc really long name, omg goes on 28 chars 2/3

0 chars PROJECT NAME Abc really long name, omg goes on and on 34 chars class TextInput extends React . Component { ... } render (< TextInput limit ={ 30 }

/>)

0 chars PROJECT NAME Abc really long name, omg goes on and on 34 chars class TextInput extends React . Component { ... } render (< TextInput renderLabel ={ renderLabel } />)

0 chars PROJECT NAME Abc really long name, omg goes on and on 34 chars class TextInput extends React . Component { ... } render (< TextInput renderLabel ={ renderLabel } />) const renderLabel

( length )

=>

{

return

< span

{ length } chars </ span

}

Render prop

0 chars PROJECT NAME Abc really long name, omg goes on and on 34 chars class TextInput extends React . Component { ... } render (< TextInput renderLabel ={ renderLabel } />) const renderLabel

( length )

=>

{

return

< span

{ length } chars </ span

}

0 chars PROJECT NAME Abc really long name, omg goes on and on 34 chars class TextInput extends React . Component { ... } render (< TextInput renderLabel ={ renderLabel } />) const renderLabel

( length )

=>

{

let className

if

( length

25 ) className

'warn'

else

if

( length

30 ) className

'error'

return

< span className ={ className }>

{ length } chars </ span

}

0 chars PROJECT NAME Abc really long name, omg goes on and on 34 chars class TextInput extends React . Component { constructor (props)

{ ... } onChange ( event )

{ ... } render ()

{ return

( < div

< input onChange ={ this . onChange . bind ( this ) /> < span

{ this . state . length } chars </ span

</ div

) } }

0 chars PROJECT NAME Abc really long name, omg goes on and on 34 chars class TextInput extends React . Component { constructor (props)

{ ... } onChange ( event )

{ ... } render ()

{ return

( < div

< input onChange ={ this . onChange . bind ( this ) /> {

this . props . renderLabel ()

} </ div

) } }

0 chars PROJECT NAME Abc really long name, omg goes on and on 34 chars class TextInput extends React . Component { constructor (props)

{ ... } onChange ( event )

{ ... } render ()

{ return

( < div

< input onChange ={ this . onChange . bind ( this ) /> {

this . props . renderLabel ( this . state . length )

} </ div

) } }

0 chars PROJECT NAME Abc really long name, omg goes on and on 34 chars class TextInput extends React . Component { constructor (props)

{ ... } onChange ( event )

{ ... } render ()

{ return

( this . props . render ( this . state . length ) ) } }

< Form

< Form.TextInput label =" email "

placeholder =" Enter

some

text"

/> < Form.TextArea label =" address "

placeholder =" Enter

some

text"

/> < Form.Switch label =“ accept? " theme =" manage " /> < Button theme =" manage ">Save Changes</ Button

</ Form

< Form

< Form.TextInput label =" email "

placeholder =" Enter

some

text"

/> < Form.TextArea label =" address "

placeholder =" Enter

some

text"

/> < Form.Switch label =“ accept? " theme =" extend " /> < Button theme =" manage ">Save Changes</ Button

</ Form

< Form

< Form.TextInput label =" email "

placeholder =" Enter

some

text"

/> < Form.TextArea label =" address "

placeholder =" Enter

some

text"

/> < Form.Switch label =“ accept? " theme =" extend " /> < Button theme =" manage ">Save Changes</ Button

</ Form

< Form

< Form.TextInput label =" email "

placeholder =" Enter

some

text"

/> < Form.TextArea label =" address "

placeholder =" Enter

some

text"

/> < Form.Switch label =“ accept? " theme =" extend " /> < Button theme =" extend ">Save Changes</ Button

</ Form

render (

< App /> )

render (

< ThemeProvider name =" manage ">

< App />

</ ThemeProvider

)

render (

< ThemeProvider name =" extend ">

< App />

</ ThemeProvider

)

Provider Component

https://avatars3.githubusercontent.com/u/17475736?s=400&v=4 ✅ ✅ ✅

render (

< ThemeProvider name =" extend ">

< App />

</ ThemeProvider

)

render (

< ThemeProvider name =" extend ">

< App />

</ ThemeProvider> )

render (

< ThemeProvider name =" extend ">

< App />

</ ThemeProvider> ) class ThemeProvider extends React . Component {

render ()

{

return

this . props . children

} }

render (

< ThemeProvider name =" extend ">

< App />

</ ThemeProvider> ) class ThemeProvider extends React . Component {

getChildContext ()

{

return

{ theme :

this . props . name }

}

render ()

{

return

this . props . children

} }

render (

< ThemeProvider name =" extend ">

< App />

</ ThemeProvider> ) class ThemeProvider extends React . Component {

getChildContext ()

{

return

{ theme :

this . props . name }

}

render ()

{

return

this . props . children

} } ThemeProvider. childContextTypes

{ theme : PropTypes . string }

render (

< ThemeProvider name =" extend ">

< App />

</ ThemeProvider> ) class ThemeProvider extends React . Component { ... } ThemeProvider. childContextTypes

{ theme : PropTypes . string }

render (

< ThemeProvider name =" extend ">

< App />

</ ThemeProvider> ) class ThemeProvider extends React . Component { ... } ThemeProvider. childContextTypes

{ theme : PropTypes . string } const Button

( props )

=>

{

return

< button className ="button">{ props . children }</ button

}

render (

< ThemeProvider name =" extend ">

< App />

</ ThemeProvider> ) class ThemeProvider extends React . Component { ... } ThemeProvider. childContextTypes

{ theme : PropTypes . string } const Button

( props )

=>

{

return

< button className ="button">{ props . children }</ button

} Button . contextTypes

{ theme : PropTypes . string }

render (

< ThemeProvider name =" extend ">

< App />

</ ThemeProvider> ) class ThemeProvider extends React . Component { ... } ThemeProvider. childContextTypes

{ theme : PropTypes . string } const Button

( props, context )

=>

{

return

< button className ="button">{ props . children }</ button

} Button . contextTypes

{ theme : PropTypes . string }

render (

< ThemeProvider name =" extend ">

< App />

</ ThemeProvider> ) class ThemeProvider extends React . Component { ... } ThemeProvider. childContextTypes

{ theme : PropTypes . string } const Button

( props, context )

=>

{

let className

'button'

'button-'

context . theme

return

< button className ={ className }>{ props . children }</ button

} Button . contextTypes

{ theme : PropTypes . string }

render (

< ThemeProvider name =" extend ">

< App />

</ ThemeProvider> )

render (

< ThemeProvider name =" manage ">

< App />

</ ThemeProvider> )

class ThemeProvider extends React . Component { ... } ThemeProvider. childContextTypes

{ theme : PropTypes . string } const Button

( props, context )

=>

{

let className

'button'

'button-'

context . theme

return

< button className ={ className }>{ props . children }</ button

} Button . contextTypes

{ theme : PropTypes . string } render (

< ThemeProvider name =" extend ">

< App />

</ ThemeProvider> )

class ThemeProvider extends React . Component { ... } ThemeProvider. childContextTypes

{ theme : PropTypes . string } const Button

( props, context )

=>

{

let className

'button'

'button-'

context . theme

return

< button className ={ className }>{ props . children }</ button

} addContext (Button) render (

< ThemeProvider name =" extend ">

< App />

</ ThemeProvider> )

class ThemeProvider extends React . Component { ... } ThemeProvider. childContextTypes

{ theme : PropTypes . string } export function addContext ( Component )

{ Component [ 'contextTypes' ]

=

{ theme : PropTypes . string

}

return Component }

const Button

( props, context )

=>

{

let className

'button'

'button-'

context . theme

return

< button className ={ className }>{ props . children }</ button

} addContext (Button)

✅

7 component patterns

I hope you learned something today

siddharthkp