将React上下文通过HOC传递给包装组件

时间:2017-08-25 02:10:35

标签: javascript reactjs ecmascript-6 redux higher-order-components

有没有办法可以通过React高阶组件将上下文传递给它包装的组件?

我有一个从其父级接收上下文的HOC,并利用该上下文执行基本的通用操作,然后包装一个也需要访问相同上下文以执行操作的子组件。例子:

HOC:

export default function withACoolThing(WrappedComponent) {
  return class DoACoolThing extends Component {
    static contextTypes = {
      actions: PropTypes.object,
    }

    @autobind
    doAThing() {
      this.context.actions.doTheThing();
    }

    render() {
      const newProps = {
        doAThing: this.doAThing,
      };

      return (
        <WrappedComponent {...this.props} {...newProps} {...this.context} />
      );
    }
  }
};

包装组件:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { autobind } from 'core-decorators';
import withACoolThing from 'lib/hocs/withACoolThing';


const propTypes = {
  doAThing: PropTypes.func,
};

const contextTypes = {
  actions: PropTypes.object,
};

@withACoolThing
export default class SomeComponent extends PureComponent {

  @autobind
  doSomethingSpecificToThisComponent(someData) {
    this.context.actions.doSomethingSpecificToThisComponent();
  }

  render() {
    const { actions } = this.context;

    return (
      <div styleName="SomeComponent">
        <SomeOtherThing onClick={() => this.doSomethingSpecificToThisComponent(someData)}>Do a Specific Thing</SomeOtherThing>
        <SomeOtherThing onClick={() => this.props.doAThing()}>Do a General Thing</SomeOtherThing>
      </div>
    );
  }
}

SomeComponent.propTypes = propTypes;
SomeComponent.contextTypes = contextTypes;

在HOC中传递{...this.context}不起作用。只要包装的组件被HOC包装,this.context就是空{}。请帮忙?有没有办法传递不涉及将其作为道具传递的上下文?

1 个答案:

答案 0 :(得分:5)

问题:

  

如果未定义contextTypes,则上下文将是一个空对象。

解决方案:

在 HOC内设置WrappedComponent.contextTypes

<强>解释

在未修复的代码中,contextTypes的{​​{1}}未设置。当SomeComponentSomeComponent修饰时,您对@withACoolThing所做的任何更改实际发生在SomeComponent,而DoACoolThing的{​​{1}}永远不会被设置所以它最终成为一个空对象contextTypes

旁注:

因为你正在扩展HOC中的SomeComponent并将其作为道具传递到这里:

{}

您应该在子组件中使用this.context之类的内容。