在组件渲染中调用高阶组件

Kay*_*ote 4 javascript higher-order-functions reactjs higher-order-components react-router-v4

一些简单的事情在这里绊倒了我的逻辑:

我有一个 HOC AnimateOnLoad,它react-router在页面组件中呈现默认内容(在内使用)。

const DefaultLayout = ({ component: Component, ...rest }) => (

   <Route
      {...rest}
      render={matchProps => (
         <div className="page-container">
            {AnimateOnLoad(
               <div className="container">
                  <Head />
                  <Nav />
                  <Component {...matchProps} />
               </div>
            )}
            <Footer />
         </div>
      )}
   />
);
Run Code Online (Sandbox Code Playgroud)

animateONLoadHOC看起来是这样的:

const AnimateOnLoad = WrappedComponent =>
   class Animator extends Component {
      constructor(props) {
         super(props);
         this.ele = React.createRef();
      }
      componentDidMount() {
         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>
         );
      }
   };
Run Code Online (Sandbox Code Playgroud)

但是,我收到一个错误:

函数作为 React 子元素无效。如果您返回 Component 而不是从 render 返回,则可能会发生这种情况。或者,您可能打算调用此函数而不是返回它。

这对我来说没有意义,因为我ComponentAnimateOnLoad();

谢谢你。

Abd*_*auf 5

你的错误的根本原因是这个

如果您返回 Component 而不是 <Component />,则可能会发生这种情况

@ShubhamKhatri Answer 将解决您的问题。我想扩大他的回答。

不要在渲染方法中使用 HOC

React 的 diffing 算法(称为 reconciliation)使用组件标识来确定它是应该更新现有的子树还是丢弃它并安装一个新的子树。如果从 render 返回的组件与从前一个 render 返回的组件相同(===),React 通过将它与新的比较递归地更新子树。如果它们不相等,则完全卸载先前的子树。

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 />;
}
Run Code Online (Sandbox Code Playgroud)

请注意在他的回答中如何在渲染之外使用 HOC。

这里的问题不仅仅与性能有关——重新挂载组件会导致该组件及其所有子组件的状态丢失。

这就是为什么在组件定义之外应用 HOC 非常重要,这样生成的组件只创建一次。然后,它的身份将在渲染中保持一致。无论如何,这通常是您想要的。

参考:https : //reactjs.org/docs/higher-order-components.html#dont-use-hocs-inside-the-render-method