There are two special kinds of abstraction with React. High order components are components that take a component as an argument and return another component.
Previously, the role of high order components was solved with mixins. A few things can still only be done with mixins, which we’ll cover below.
Let’s write a high order function that passes a random number to the child via props. Props are how high order components talk to child components. You also need to make sure you pass any extra props down using the {...this.props}
syntax.
function
providesRandomNumber
(
Component
)
{
return
class
RandomNumberProvider
extends
React
.
Component
{
render
(){
return
<
Component
{...
this
.
props
}
randomNumber
=
{
4
}
/>
;
}
}
}
We can then use this function to wrap a component.
var
MyComponent
=
providesRandomNumber
(
class
MyComponent
extends
React
.
Component
{
render
(){
return
(
<
div
>
The
random
number
is
{
this
.
props
.
randomNumber
}
<
/div>
);
}
}
);
This is a bit cleaner with the es7 decorators proposal.
@
providesRandomNumber
class
MyComponent
extends
React
.
Component
{
render
(){
return
(
<
div
>
The
random
number
is
{
this
.
props
.
randomNumber
}
<
/div>
);
}
}
Often a high order component takes options. You can curry it, which means it can be called like hoc(Component)
, hoc({}, Component)
, or hoc({})(Component)
.
function
hoc
(
options
,
Component
){
if
(
typeof
options
===
'function'
)
return
hoc
({},
options
);
if
(
arguments
.
length
<
2
)
return
hoc
.
bind
(
null
,
options
||
{});
return
class
...
}
If you have a mixin, you can create a high order component from the mixin and pass things down as props.
import {History} from 'react-router'; function providesRouter(Component){ return React.createClass({ mixins: [History], render(){ return <Component {...this.props} router={{ pushState: this.pushState, }} /> } }); }
As a general rule, static properties should be passed down to the component you create.
function
providesFoo
(
Component
){
return
Object
.
assign
(
class
Foo
extends
React
.
Component
{
render
(){
...
}
},
Component
);
}
High order components are typically used for global events, binding to flux stores, timers, and any other imperative APIs that you want to use declaratively.
High order components are one of the most powerful tools for eliminating code repetition, and keeping your components focused on what makes them special. They allow you to use powerful abstractions, and some problems can’t be solved elegantly without them.
Even if you only intend to use a high order component in a single component, it allows you to describe a certain behavior or role, and provide that to the component. They reduce the amount of code you need to read before understanding a component, and allow you to do ugly things (such as managing __intervals) without making your component ugly.
When reading the next chapter about DOM, think about the behaviors and roles you could pull out of the components, or even try for yourself.
3.142.164.100