javascript - Calling a Higher-Order Component within Component render - Stack Overflow

Something simple is tripping up my logic here:I have a HOC AnimateOnLoad which renders a default conten

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 badges
Add a ment  | 

2 Answers 2

Reset to default 5

Root 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条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信