реагировать объединить разные оболочки - PullRequest
0 голосов
/ 25 июня 2018

Мы начинаем новый проект в React. И нам нужно использовать:

  • React Context API
  • i18n (реаги.i18nex)
  • GraphQL (клиент Apollo)
  • Redux
  • CCS-in-JS (стилизованные компоненты или афодит)

Дело в том, что любая из этих реализаций оборачивает компонент и передает ему некоторые реквизиты или использует функции в качестве дочерних элементов.

И я хочу сохранить мои компоненты отделенными и по возможности чистить.

Как мне структурировать оболочки?

* * Пример 1 022

Главная

<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>

Redux:

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


export default connect(
  mapStateToProps,
)(Home);

Как видите, компонент Home получает изолированные реквизиты из многих источников.

Как я могу управлять ими и поддерживать их развязанными? Есть какой-то композитор ?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Спасибо за вашу помощь!Вы все.Я реализовал 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;

Опять же, большое спасибо!

0 голосов
/ 25 июня 2018

Я думаю, что вы можете преобразовать это в 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);
...