Something simple is tripping up my logic here:
I have a HOC AnimateOnLoad
which renders a default content (used within react-router
) within the page ponent.
const DefaultLayout = ({ ponent: Component, ...rest }) => (
<Route
{...rest}
render={matchProps => (
<div className="page-container">
{AnimateOnLoad(
<div className="container">
<Head />
<Nav />
<Component {...matchProps} />
</div>
)}
<Footer />
</div>
)}
/>
);
The animateONLoad
HOC looks like this:
const AnimateOnLoad = WrappedComponent =>
class Animator extends Component {
constructor(props) {
super(props);
this.ele = React.createRef();
}
ponentDidMount() {
Kute.fromTo(
this.ele.current,
{ opacity: 0.3 },
{ opacity: 1, duration: 120 }
).start();
}
render() {
return (
<div className="animator" ref={this.ele}>
<WrappedComponent {...this.props} />
</div>
);
}
};
However, I am getting an error:
Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.
which doesn't make sense to me as I am returning a Component
from AnimateOnLoad()
;
Thank you.
Something simple is tripping up my logic here:
I have a HOC AnimateOnLoad
which renders a default content (used within react-router
) within the page ponent.
const DefaultLayout = ({ ponent: Component, ...rest }) => (
<Route
{...rest}
render={matchProps => (
<div className="page-container">
{AnimateOnLoad(
<div className="container">
<Head />
<Nav />
<Component {...matchProps} />
</div>
)}
<Footer />
</div>
)}
/>
);
The animateONLoad
HOC looks like this:
const AnimateOnLoad = WrappedComponent =>
class Animator extends Component {
constructor(props) {
super(props);
this.ele = React.createRef();
}
ponentDidMount() {
Kute.fromTo(
this.ele.current,
{ opacity: 0.3 },
{ opacity: 1, duration: 120 }
).start();
}
render() {
return (
<div className="animator" ref={this.ele}>
<WrappedComponent {...this.props} />
</div>
);
}
};
However, I am getting an error:
Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.
which doesn't make sense to me as I am returning a Component
from AnimateOnLoad()
;
Thank you.
Share Improve this question edited May 16, 2020 at 14:52 Penny Liu 17.6k5 gold badges86 silver badges108 bronze badges asked Jul 23, 2018 at 17:00 KayoteKayote 15.7k26 gold badges96 silver badges152 bronze badges2 Answers
Reset to default 5Root cause of your error is this
This may happen if you return a Component instead of <Component />
@ShubhamKhatri Answer will resolve your issue. I want to expand his answer.
Don’t Use HOCs Inside the render Method
React’s diffing algorithm (called reconciliation) uses ponent identity to determine whether it should update the existing subtree or throw it away and mount a new one. If the ponent returned from render is identical (===) to the ponent from the previous render, React recursively updates the subtree by diffing it with the new one. If they’re not equal, the previous subtree is unmounted pletely.
render() {
// A new version of Animate is created on every render
// Animate1 !== Animate2
const Animate = AnimateOnLoad(MyComponent);
// That causes the entire subtree to unmount/remount each time!
return <Animate />;
}
Notice how HOC is used outside render in his answer.
The problem here isn’t just about performance — remounting a ponent causes the state of that ponent and all of its children to be lost.
That's why its very important to apply HOCs outside the ponent definition so that the resulting ponent is created only once. Then, its identity will be consistent across renders. This is usually what you want, anyway.
Reference: https://reactjs/docs/higher-order-ponents.html#dont-use-hocs-inside-the-render-method
You aren't using the AnimateOnLoad
HOC correctly. You need to use it like
const CustomComp = (matchProps) => (
<div className="container">
<Head />
<Nav />
<Component {...matchProps} />
</div>
);
const HOCComponent = AnimateOnLoad(CustomComp)
const DefaultLayout = ({ ponent: Component, ...rest }) => (
<Route
{...rest}
render={matchProps => (
<div className="page-container">
<HOCComponent {...matchProps}/>
<Footer />
</div>
)}
/>
);
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745601443a4635422.html
评论列表(0条)