By Sarah Herr
Higher order components (HOCs) are components in React that take a component as an argument and return an enhanced component
const CartHeader = (props) => {
if (props.user) {
return <p>Welcome, {props.user.name}</p>
} else {
return <p>Log in to checkout</p>
}
}
The component to wrap:
const CartHeaderwithUser = withUser(CartHeader);
Implementing the HOC:
function withUser(Component) {
const userInfo = {
name: "Sarah Herr",
address: "123 W 14th St New York, NY",
cardNo: 123456789,
cardExp: 0419
};
return function(props) {
return <Component user={userInfo} {...props} />
}
}
The higher order component:
function withStyle(Component) {
return class fancyComponent extends React.Component {
render() {
return (
<div className="sassy" style={{display: 'block'}}>
<Component {...this.props} />
</div>
)
}
}
}
function loggedIn(MessagesComponent) {
return class Conditional extends MessagesComponent {
render() {
if (this.props.loggedIn) {
return super.render()
} else {
return null
}
}
}
}
class Cat extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
color: '',
food: ''
}
this.handleName = this.handleName.bind(this);
this.handleColor = this.handleColor.bind(this);
this.handleFood = this.handleFood.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleName(evt) {
evt.preventDefault();
this.setState({
name: evt.target.value
})
}
handleColor(evt) {
evt.preventDefault();
this.setState({
color: evt.target.value
})
}
handleFood(evt) {
evt.preventDefault();
this.setState({
food: evt.target.value
})
}
handleSubmit(evt) {
store.dispatch(addCat(this.state))
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>Name:</label>
<input onChange={this.handleName} />
<label>Color:</label>
<input onChange={this.handleColor} />
<label>Food:</label>
<input onChange={this.handleFood} />
<button type='submit'>Add Cat</button>
</form>
</div>
)
}
}
function withForm(WrappedComponent, actionCreator) {
return class extends React.Component {
constructor(props) {
super(props);
this.handleInput = this.handleInput.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleInput(evt) {
evt.preventDefault();
this.setState({
evt.target.name: evt.target.value
})
}
handleSubmit(evt) {
store.dispatch(actionCreator(this.state))
}
render() {
const formProps = {
handleInput: this.handleInput,
handleSubmit: this.handleSubmit
}
return <WrappedComponent form={formProps} {…this.props} />
}
}
}
const Cat = (props) => {
return (
<div>
<form onSubmit={props.form.handleSubmit}>
<label>Name:</label>
<input name="name" onChange={props.form.handleInput} />
<label>Color:</label>
<input name="color" onChange={props.form.handleInput} />
<label>Food:</label>
<input name="food" onChange={props.form.handleInput} />
<button type='submit'>Add Cat</button>
</form>
</div>
)
}
import { addCat } from '../action-creators/animals'
const CatWithForm = withForm(Cat, addCat)
import { addUnicorn } from '../action-creators/animals'
import { withForm } from '../higher-order-components'
const UnicornWithForm = withForm(Unicorn, addUnicorn)
const Unicorn = (props) => {
return (
<div>
<form onSubmit={props.form.handleSubmit}>
<label>Name:</label>
<input name="name" onChange={props.form.handleInput} />
<label>Horn length:</label>
<input name="horn" onChange={props.form.handleInput} />
<label>Sparkle Color:</label>
<input name="sparkle" onChange={props.form.handleInput} />
<label>Favorite Cloud:</label>
<input name="cloud" onChange={props.form.handleInput} />
<button type='submit'>Add Unicorn</button>
</form>
</div>
)
}