-
-
Save sebmarkbage/ef0bf1f338a7182b6775 to your computer and use it in GitHub Desktop.
import { Component } from "React"; | |
export var Enhance = ComposedComponent => class extends Component { | |
constructor() { | |
this.state = { data: null }; | |
} | |
componentDidMount() { | |
this.setState({ data: 'Hello' }); | |
} | |
render() { | |
return <ComposedComponent {...this.props} data={this.state.data} />; | |
} | |
}; |
import { Enhance } from "./Enhance"; | |
class MyComponent { | |
render() { | |
if (!this.data) return <div>Waiting...</div>; | |
return <div>{this.data}</div>; | |
} | |
} | |
export default Enhance(MyComponent); // Enhanced component |
I have no idea what you all above posted because none of them worked. Did you test them? This works .......
import React from 'react';
import ReactDOM from 'react-dom';
import { MyEnhance } from "./enhance";
@MyEnhance
class MyComponent extends React.Component {
render() {
if (!this.props.data) return <div>Waiting...</div>;
return <div>{this.props.data}</div>;
}
};
ReactDOM.render(<MyComponent />, document.getElementById('root'));
import React, { Component } from "React";
export var MyEnhance = ComposedComponent => class extends Component {
constructor() {
super();
this.state = { data: null };
}
componentDidMount() {
this.setState({ data: 'Hello You' });
}
render() {
const temp = this.state.data;
return <ComposedComponent {...this.props} data={ temp } />;
}
};
@JoeGrasso ES6 changed in between the original post and your reading, thus it all did work just fine at the time. See about halfway through the thread for someone commenting about pretty much the same thing you did.
Thoughts on using something like static displayName = "HigherOrderComponentName["+(Component.displayName || Component.name)+"]";
so it shows up like <HigherOrderComponentName[ComposedComponentName] ...>
in the dev tools?
domcom(https://github.com/taijiweb/domcom) can have true inheritance.
This are minimal
skeleton for higher order components
If your higher order component need state
or lifecycle methods
use this:
const hoc = C => class _hoc extends React.Component {
render() {
return <C { ...this.props }/>;
}
}
For debugging purpose with React Tools I match function name with class name, Ex: hoc
match _hoc
. This way I know what is a "real" component and what a HOC, it looks like a function.
If you don´t need state
or lifecycle methods
on your HOC this snip is more functional:
const hoc = C => function _hoc(props) {
return <C { ...props }/>;
}
Same like first snip, I use a named function _hoc
maching hoc
for debugging purpose.
I've written about some real world examples of higher order components we use in our application here:
http://techblog.realestate.com.au/reactjs-real-world-examples-of-higher-order-components/
Comments are more than welcome
I use this way
var MyComponent = Enhance(class extends Component {
render() {
if (!this.data) return
return
}
});
export default MyComponent; // Enhanced component
But it meets a problem "Minified exception occurred;use the non-minfied dev environment for the full error message and additional helpful warnings." How to deal with this probleam?
I created a forked showing how I used this with ES7 decorators: (Also fixes a few issue with this gist)
https://gist.github.com/jeromepl/2f7df563f273563261690221c22aa0af
I created two packages which you can use for creating of high-order components.
With react-provide-props you can easily create high-order component which will add props to other components. It will create state-less high-order compoment.
Second package react-high-order-provider you can use for state-full high-order components where you can define your own logic.
Both libraries will create function compatible with ES7 decorators as well.
Hey guys! you can checkout my example.
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
let HOC = WrappedComponent => {
return class extends Component{
constructor(props){
super(props);
this.state = {
name : ' '
};
this.onNameChange = this.onNameChange.bind(this)
}
onNameChange(e){
this.setState({
name : e.target.value
})
}
render(){
const newProps = {
value : this.state.name,
onChange : this.onNameChange
};
return <WrappedComponent {...this.props} {...newProps} {...this.state}/>
}
}
};
let App = HOC((props) => {
return(
<div> <input type="text" {...props}/> <p>{props.name}</p> </div>
)
});
ReactDOM.render(
<App />
,
document.getElementById('root')
);
@seeden
I love the libraries, they are both great 👍
Interesting examples, is there any particular advantage of attempting to enforce OO over HOC? Anyhow, fun to follow the thread. Pedantic point of note, why in all the ES6 / ES7 examples are there still references to "var"? Also arrow functions implicitly return whatever is after them, so if no multi-expressions are needed, then no need for the curlies!
Anyhow.. I digress....
I love this gist, because it shows a simple example for a higher order component.
I am not sure if this is the perfect place, but maybe people are interested to read a more elaborated gentle introduction to higher order components when they come across this gist looking for HOC examples.
Hello everyone, I came across a good blog which is about React Higher Order components. It was completely awesome and explained in well manner. Have a look into it: Link
I hope you will learn knew content about React HOCs.
Regards,
ReactJS Online Training
Thanks for the links 👍 @rwieruch @Ramyace4455
is this the first ever written HOC ?
Wow, the React community really flubbed on terminology here. In this gist, the component utilizing what we call the HoC is called the HoC, whereas the thing we call the HoC is called an "Enhancer." This makes way more sense, as a "HoC," as it is known today, is not itself a component at all. Sad!!
Not quite see the difference between HoC and old decorator pattern. I would say HoC is a nice react implementation of decorator pattern.
Your constructor needs super(props)
as the first line
What's the difference between HOC and
this.props.children
aside of the syntax? A parent component can modify the children's props, abstract state, and control the way the child instance renders. It'll be interesting to know what are the things both patterns have in common and where do they differ