反应结合不同的包装器

react combine differents wrappers

我们正在用 React 开始一个新项目。 我们需要使用:

问题是任何这个实现都包装了一个组件并传递给它一些道具或使用函数作为 children。

而且我想让我的组件保持解耦并尽可能清洁。

如何构造包装器?

例子

首页

<Home {...props} />

上下文:

 <ThemeContext.Consumer>
   { theme=> <Home {...theme} programa={theme} /> }
 </ThemeContext.Consumer>

i18n:

 <I18n>
    {t => <Home text={t("translated text")} /> }
 </I18n>

GraphQL:

<Query query={GET_PROGRAMA}>
  {({ data }) => <Home data={data} />}
</Query>

终极版:

const mapStateToProps = state => ({
    user: "some user"
});


export default connect(
  mapStateToProps,
)(Home);

如您所见,Home 组件从许多来源接收孤立的道具。

如何管理 ir 并使其解耦?有某种作曲家?

谢谢!

我认为您可以将其转换为 HOC,为您处理所有组件包装:

const withWrappers = WrappedComponent => {
  return class extends React.Component {
    render () {
      return (
        <ThemeContext.Consumer>
          { theme =>
            <I18n>
              { t =>
                <Query query={GET_PROGRAMA}>
                  { ({ data }) => 
                    <WrappedComponent
                      {...this.props}
                      {...theme}
                      programa={theme}
                      data={data}
                      text={t("translated text")}
                    />
                  }
                </Query>
              }
            </I18n>
          }
        </ThemeContext.Consumer>
      )
    }
  }
}

用法:

class Home extends React.Component {
    render () {
      return (
        <div>Home</div>
      )
    }
}

export default withWrappers(Home);

感谢您的帮助!你们所有人。 我已经实现了一个 HOC,就像你向我提出的一样,并将 GraphQL 组件放在外面:

import React from "react";
import PropTypes from "prop-types";
import { mergeStyles } from "js/utils";
import { I18n } from "react-i18next";
import { TemplateContext } from "js/template-context";

const Wrapper = ({ Component, getStylesFromTemplate }) => props => {
  const { classes } = props;
  return (
    <TemplateContext.Consumer>
      {programa => {
        const { template } = programa;
        const stylesFromTemplate = getStylesFromTemplate(template);
        const styles = mergeStyles({ classes, stylesFromTemplate });
        return (
          <I18n>
            {(t, { i18n }) => {
              return (
                <Component
                  t={t}
                  styles={styles}
                  programa={programa}
                  {...props}
                />
              );
            }}
          </I18n>
        );
      }}
    </TemplateContext.Consumer>
  );
};

Wrapper.propTypes = {
  classes: PropTypes.object.isRequired
};

export default Wrapper;

再次感谢您!