Reputation: 37
Why does the higherOrderComponent1 function doesn't work and the higherOrderComponent2 works as expected? According the documentation I don't seem to be doing something wrong, but as it is not working, I must be doing something wrong :-)
https://facebook.github.io/react/docs/higher-order-components.html
You can find a sandbox version here: https://codesandbox.io/s/MRwMnA2R
import React, {Component} from 'react';
import {render} from 'react-dom';
const higherOrderComponent1 = (name) => {
return class extends Component {
render() {
<div>{`Hi ${name}`}</div>
}
}
};
const higherOrderComponent2 = (name) => (
<div>{`Hi ${name}`}</div>
);
const App = () => (
higherOrderComponent1("Peter")
);
render(<App />, document.getElementById('root'));
Upvotes: 0
Views: 857
Reputation: 5645
Ok you're a little off on how to use a HOC. Here is a simplistic example that I will explain.
function giveColor( WrappedComponent, color ) {
return class extends Component {
componentDidMount() {
this.wrapperEl.children[ 0 ].style.color = color;
}
render() {
console.log(this.props)
return (
<div ref={ ( el ) => this.wrapperEl = el }>
<WrappedComponent { ...this.props } />
</div>
);
}
}
}
const PrintName = ({ name }) => (
<div>{ name }</div>
);
const PrintRedName = giveColor( PrintName, "#ff0000" );
You would use PrintRedName as follows: <PrintRedName name="Bubowski" />
The name
property you provide will get passed through to the wrapped component because of the { ...props }
on the <WrappedComponent />
call in the render method of the returned class from the HOC.
The HOC is used as a function on another component as follows: const PrintRedName = giveColor( PrintName, "#ff0000" );
I'm calling the giveColor HOC with PrintName component as the first argument, and the color I want to set as the second.
In the HOC I wrap the WrappedComponent in a div that I give a ref
that I use to change the style.color property of the first child of the ref
.
This is a contrived example, but I hope it helps you understand :)
Some good examples of HOCs are connect()
from react-redux and withRouter()
from react-router
EDIT: In response to your latest question:
I edited your linked to code to the following to make it work, please read the in code comments.
const wrapComponent = (WrappedComponent) =>
class extends Component {
render() {
return (
<div>
I wrapped:
<WrappedComponent {...this.props} />
</div>
)
}
}
const ComponentA = ({name}) => <div><b>{name}</b></div>;
const ComponentB = wrapComponent(ComponentA);
// You had...
/*
No need to wrap a component wrapping itself, but the problem here is,
You're nesting evalutions by doing { ...code } inside
() => ( single evaluation )
const App = () => (
{ wrapComponent(ComponentB) }
)
*/
const App = () => (
<ComponentB name="My name" />
)
render(<App />, document.getElementById('root'));
Upvotes: 1