React cloneElement和组件实例

时间:2016-11-08 15:36:54

标签: reactjs

我有以下高阶组件,我试图将其包装在作为道具提供的容器元素中:

import React, { PropTypes } from 'react';

export default (Component) => {
  return class extends React.Component {
    static propTypes = {
      containerElement: PropTypes.element
    }

    static defaultProps = {
      containerElement: <div />
    };

    componentDidMount() {
      console.log(this.el);
    }

    render() {
      const containerProps = {
        ref: (el) => this.el = el
      };

      return React.cloneElement(containerElement, containerProps, Component);
    };
  }
}

然后我将这样的组件包装起来:

export default AnimationComponent(reduxForm({
  form: 'newResultForm',
  validate
})(NewResultForm));

但是当我在componentDidMount中记录该元素时,它是一个空的<div/>

为什么传入的组件不是新创建的容器元素的子元素?

1 个答案:

答案 0 :(得分:1)

您编写高阶组件的方法有点不正统。反应开发人员通常不必编写接受组件的函数并返回新的类定义,除非他们自己编写类似redux-form的东西。也许不是将Component作为参数传递,而是查看在props.children中传递它是否适合您:

<AnimationComponent>{NewResultForm}</AnimationComponent>

我定义了AnimationComponent,如下所示:

export default class AnimationComponent extends React.Component {
    static propTypes = {
        containerElement: React.PropTypes.element
    };

    static defaultProps = {
        containerElement: <div />
    };

    render () {
        // For each child of this component,
        // assign each a ref and store it on this component as this[`child${index}`]
        // e.g. this.child1, this.child2, ...
        // Then, wrap each child in the container passed in on props:

        return React.Children.map(this.props.children, (child, index) =>
            React.cloneElement(
                this.props.containerElement,
                {ref: ref => this[`child${index}`] = ref},
                React.cloneElement(child)
            )
        );
    }
}

不是将表单组件包装在AnimationComponent中,而是导出连接的表单类:

export default reduxForm({
    form: 'newResultForm',
    validate
})(NewResultForm));

现在我们可以将它配置为我们最终渲染表单的喜好,而不是停留在NewResultForm文件中如何配置AnimationComponent。除了提供灵活性之外,配置AnimationComponent所需的信息在呈现的位置更为相关:

export default class MyApp extends React.Component {
    render() {
        return (
            <AnimationComponent containerComponent="span">
                <NewResultForm />
            </AnimationComponent>
        );
    }
}

我希望这有帮助!