Skip to content

Commit c9040d3

Browse files
authored
Create high-order-component.md
1 parent 1fac921 commit c9040d3

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed

high-order-component.md

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# High Order Components Pattern
2+
3+
> HOC favors single responsibility principle: Higher order component is a function that takes one component and returns a new component.
4+
5+
A common usage of HOC is to provide the wrapped component with additional props or modify existing prop values. This technique is called ```props proxy```.
6+
7+
**Example: High Order Component**
8+
9+
```js
10+
function withNewFunctionality(WrappedComponent) {
11+
return class NewFunctionality extends Component {
12+
render() {
13+
const newProp = 'Value';
14+
const propsProxy = {
15+
...this.props,
16+
// Alter existing prop:
17+
ownProp: this.props.ownProp + ' was modified',
18+
// Add new prop:
19+
newProp
20+
};
21+
return <WrappedComponent {...propsProxy} />;
22+
}
23+
}
24+
}
25+
const MyNewComponent = withNewFunctionality(MyComponent);
26+
```
27+
> What can be done with Props Proxy?
28+
> * Manipulating props
29+
> * Accessing the instance via Refs
30+
> * Accessing the instance via Refs
31+
> * Wrapping the WrappedComponent with other elements
32+
33+
## Manipulating Props
34+
35+
You can read, add, edit and remove the props that are being passed to the WrappedComponent.
36+
37+
```js
38+
function ppHOC(WrappedComponent) {
39+
return class PP extends React.Component {
40+
render() {
41+
const newProps = {
42+
user: currentLoggedInUser
43+
}
44+
return <WrappedComponent {...this.props} {...newProps}/>
45+
}
46+
}
47+
}
48+
```
49+
50+
## Accessing the instance via Refs
51+
52+
You can access this (the instance of the WrappedComponent) with a ref, but you will need a full initial normal render process of the WrappedComponent for the ref to be calculated, that means that you need to return the WrappedComponent element from the HOC render method, let React do it’s reconciliation process and just then you will have a ref to the WrappedComponent instance.
53+
54+
```js
55+
function refsHOC(WrappedComponent) {
56+
return class RefsHOC extends React.Component {
57+
proc(wrappedComponentInstance) {
58+
wrappedComponentInstance.method()
59+
}
60+
61+
render() {
62+
const props = Object.assign({}, this.props, {ref: this.proc.bind(this)})
63+
return <WrappedComponent {...props}/>
64+
}
65+
}
66+
}
67+
```
68+
69+
When the WrappedComponent is rendered the ref callback will be executed, and then you will have a reference to the WrappedComponent’s instance. This can be used for reading/adding instance props and to call instance methods.
70+
71+
## State abstraction
72+
73+
You can abstract state by providing props and callbacks to the WrappedComponent, very similar to how smart components will deal with dumb components.
74+
75+
```js
76+
function ppHOC(WrappedComponent) {
77+
return class PP extends React.Component {
78+
constructor(props) {
79+
super(props)
80+
this.state = {
81+
name: ''
82+
}
83+
84+
this.onNameChange = this.onNameChange.bind(this)
85+
}
86+
onNameChange(event) {
87+
this.setState({
88+
name: event.target.value
89+
})
90+
}
91+
render() {
92+
const newProps = {
93+
name: {
94+
value: this.state.name,
95+
onChange: this.onNameChange
96+
}
97+
}
98+
return <WrappedComponent {...this.props} {...newProps}/>
99+
}
100+
}
101+
}
102+
```
103+
104+
## Wrapping the WrappedComponent with other elements
105+
106+
You can wrap the WrappedComponent with other components and elements for styling, layout or other purposes.
107+
108+
```js
109+
function ppHOC(WrappedComponent) {
110+
return class PP extends React.Component {
111+
render() {
112+
return (
113+
<div style={{display: 'block'}}>
114+
<WrappedComponent {...this.props}/>
115+
</div>
116+
)
117+
}
118+
}
119+
}
120+
```
121+
122+
## Render Hijacking
123+
124+
You can also hook into render mechanism by altering elements that wrapped component renders. This HOC technique is named render highjacking.
125+
126+
```js
127+
function withModifiedChildren(WrappedComponent) {
128+
return class ModifiedChildren extends WrappedComponent {
129+
render() {
130+
const rootElement = super.render();
131+
const newChildren = [
132+
...rootElement.props.children,
133+
// Insert a new child:
134+
<div>New child</div>
135+
];
136+
return React.cloneElement(
137+
rootElement,
138+
rootElement.props,
139+
newChildren
140+
);
141+
}
142+
}
143+
}
144+
const MyNewComponent = withModifiedChildren(MyComponent);
145+
```

0 commit comments

Comments
 (0)