简体   繁体   English

如何为渲染和逻辑重构反应组件?

[英]How to refactor react component separate for rendering and logic?

I have react component:我有反应组件:

    function FavoritesListItem({ merchant, config, isFavorited }) {
  const {
    name, id, logoUrls = {}, offersCount, rebate, showRebate,
  } = merchant;
  const { rebateOptions } = config;

  return (
  const renderActiveMerchant = () => (
    <div
      className="mn_favoriteMerchant"
      data-merchant-id={id}
      data-merchant-name={name}
      role="listitem"
      data-test="favorite-merchant"
    >
      <div className="mn_favoriteMerchantInner">
        <MerchantExperienceLink
          className="mn_favoriteMerchantLink"
          merchant={merchant}
          title={`Opens merchant detail page at ${name}`}
        >
          <FavoriteIcon
            merchantId={id}
            merchantName={name}
            labelUnfavorite={`Remove ${name} from Favorites list`}
            showSpinner={!isFavorited}
          />
          <div className="mn_logo"><img data-test="favorited-merchant-logo" src={logoUrls._120x60} alt={name} /></div>
          <p className="mn_offersCount" data-test="favorited-merchant-offers-count">{offersCount} offers available </p>
        </MerchantExperienceLink>
        {rebate && (
          <MerchantClickUrlLink className="mn_favoriteMerchantRebateLink" merchant={merchant}>
            <div className="mn_rebate">
              {showRebate
              ? <MerchantRebate {...rebate} {...rebateOptions} />
              : <MerchantNoRebateLabel />}
                ? <MerchantRebate {...rebate} {...rebateOptions} />
                : <MerchantNoRebateLabel />}
            </div>
          </MerchantClickUrlLink>
        )}
      </div>
    </div>
  );

  const renderDeactivatedMerchant = () => (
     <div
      className="mn_favoriteMerchant"
      data-merchant-id={id}
      data-merchant-name={name}
      role="listitem"
      data-test="favorite-merchant"
    >
      <div className="mn_favoriteMerchantInner">
        <MerchantExperienceLink
          className="mn_favoriteMerchantLink"
          merchant={merchant}
          title={`Opens merchant detail page at ${name}`}
        >
          <FavoriteIcon
            merchantId={id}
            merchantName={name}
            labelUnfavorite={`Remove ${name} from Favorites list`}
            showSpinner={!isFavorited}
          />
          <div className="mn_logo mn_noRebateMerchantLogo">
            <img data-test="favorited-merchant-logo" src={logoUrls._120x60} alt={name} />
          </div>
          {rebate && (
            <div className="mn_rebate mn_deactivatedRebate">
              {
                showRebate
                ? <MerchantNoRebateLabel />
                : <MerchantRebate {...rebate} />
              }
            </div>
        )}
        </MerchantExperienceLink>
      </div>
    </div>
  );

  return (
    merchant.type === 'Deactivated Merchant' ? renderDeactivatedMerchant() : renderActiveMerchant()
  );
}

const mapStateToProps = () => {
  const selectFavoriteByMerchantId = makeSelectFavoriteByMerchantId();
  return (state, { merchant }) => ({
    isFavorited: selectFavoriteByMerchantId(state, merchant.id),
  });
};
export default connect(mapStateToProps)(FavoritesListItem);

and need to refactor it to 2 separate components which will be just render renderDeactivatedMerchant and renderActiveMerchant.并且需要将其重构为 2 个单独的组件,它们将仅渲染 renderDeactivatedMerchant 和 renderActiveMerchant。 All other logic should be in this component FavoritesListItem所有其他逻辑都应该在这个组件中 FavoritesListItem
So I created components this way:所以我以这种方式创建了组件:

    export class FavoritesListItemDeactivatedMerchant extends Component ({ merchant, config, isFavorited }) {
  render() {
      const { merchant, config, isFavorited } = this.props;
      const {
        name, id, logoUrls = {}, rebate, showRebate,
      } = merchant;
      const { rebateOptions } = config;

      return (
        <div
          className="mn_favoriteMerchant"
          data-merchant-id={id}
          data-merchant-name={name}
          role="listitem"
          data-test="favorite-merchant"
        >
          <div className="mn_favoriteMerchantInner">
            <MerchantExperienceLink
              className="mn_favoriteMerchantLink"
              merchant={merchant}
              title={`Opens merchant detail page at ${name}`}
            >
              <FavoriteIcon
                merchantId={id}
                merchantName={name}
                labelUnfavorite={`Remove ${name} from Favorites list`}
                showSpinner={!isFavorited}
              />
              <div className="mn_logo mn_noRebateMerchantLogo">
                <img data-test="favorited-merchant-logo" src={logoUrls._120x60} alt={name} />
              </div>
              {rebate && (
                <div className="mn_rebate mn_deactivatedRebate">
                {
                 showRebate
                  ? <MerchantNoRebateLabel />
                  : <MerchantRebate {...rebate} />
                }
                </div>
              )}
            </MerchantExperienceLink>
          </div>
        </div>
      );
}
}

const mapStateToProps = () => {
  const selectFavoriteByMerchantId = makeSelectFavoriteByMerchantId();
  return (state, { merchant }) => ({
    isFavorited: selectFavoriteByMerchantId(state, merchant.id),
 });
};

export default connect(mapStateToProps)(FavoritesListItemDeactivatedMerchant);

Project builded without errors and also no errors in console.项目构建没有错误,控制台也没有错误。 But it's not render this component in browser.但它不会在浏览器中呈现这个组件。 What I'm doing wrong?我做错了什么? Please, help.请帮忙。

You have confused the syntax for function and class components and created a weird mash-up that combines both:您混淆了 function 和 class 组件的语法,并创建了一个将两者结合在一起的奇怪混搭:

export class FavoritesListItemDeactivatedMerchant extends Component ({ merchant, config, isFavorited }) {

Those props make no sense in a class: I think you meant to write this:这些道具在 class 中毫无意义:我认为您打算这样写:

export const FavoritesListItemDeactivatedMerchant = ({ merchant, config, isFavorited }) => {

or或者

export function FavoritesListItemDeactivatedMerchant({ merchant, config, isFavorited }) {

Personally I think you can improve this code by having a shared RenderMerchant with a prop isDeactivated instead of having separate components for active and deactivated.就我个人而言,我认为您可以通过共享RenderMerchant和 prop isDeactivated来改进此代码,而不是使用单独的组件来激活和停用。 There is a lot of repeated code between the two cases which you want to avoid.您要避免的两种情况之间有很多重复的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM