Reputation: 2506
I'm trying to pass the function from high order component outside the class because I need to call it but it is also needed to be pass back. Hard to explain, here's the code:
Wrapped Component:
class foo extends React.Component {
....
}
foo.list = [
{
name: "Home",
action: this.props.funcFromHoc //this.props.from foo class, how can i access this because it is outside the component?
}
]
export default bar(foo);
High Order Component:
export default function bar(WrappedComponent) {
funcFromHoc() {
alert("Hello from HOC function!");
}
render() {
return (
<WrappedComponent
{ ...this.props }
funcFromHoc={ this.funcFromHoc }
);
}
}
What I'm actually doing:
I have a base screen (HOC)
with a 2 drawers
, that has some functions that controls their behavior. I need this 2 drawers on many screens
that I'll make, I don't want to put the configuration of the drawer for every screens, that's why I create a HOC for this. My problem is, the list
on the drawer on HOC is dynamic
on each screens, and they have specific function
that I set on each screens, how can I pass a function
from the screen component
to HOC?
Am I missing something or this? Am I doing it wrong? Did I missed some of the proper usage of High Order Components? Or what method should I use for this? Any hint or help will be very much appreciated. Thank you.
Upvotes: 0
Views: 1095
Reputation: 2506
I've found a solution, it solves my problem using Inheritance Inversion.
class foo extends React.Component {
list() {
return [
{
name: "Home",
action: this.funcFromHoc //successfully accessed it here!
}
];
}
}
export default bar(foo);
(High Order Component):
export default function bar(WrappedComponent) {
return class Bar extends WrappedComponent {
funcFromHoc() {
alert("Hello from HOC function!");
}
render() {
return (
//call super.list() here to populate drawer list
{super.render()}
);
}
}
}
Upvotes: 1
Reputation: 1153
It sounds like you want to be able to pass additional parameters to the HOC. You could pass a mapping function when you call the HOC, like the color variable below. Note the HOC is defined slightly differently as well in order to take additional arguments.
edit: nevermind, you won't have access to funcFromFoo unless it is a prop of foo (i.e. defined in mapDispatchToProps). heh- i tried. may need to rethink the design so this isn't a requirement.
function doSomethingWithList(props) {
const { actionName, funcFromHOC, funcFromFooProps } = props;
if (actionName === 'Home') {
funcFromHOC();
} else {
funcFromFooProps();
}
};
const makeToggleable = (WrappedComponent, color) => {
return class ToggleableComponent extends React.Component {
constructor(props) {
super(props);
this.state = { toggled: false };
this.toggleColor = this.toggleColor.bind(this);
}
toggleColor() {
this.setState({ toggled: !this.state.toggled });
}
render() {
const fontColor = this.state.toggled? color: 'black';
return (
<WrappedComponent { ...this.props }
style={{color: fontColor}}
onClick={this.toggleColor} />
);
}
}
}
export default makeToggleable(BaseComponent, 'red');
const listItems = [ 'Home', 'Other' ];
export default bar(foo, listItems, doSomethingWithList);
pass listItems and doSomethingWithList for OP's question, modify HOC to call doSomethingWithList with props
example code from https://spin.atomicobject.com/2017/03/02/higher-order-components-in-react/
Upvotes: 0