簡體   English   中英

如何為渲染和邏輯重構反應組件?

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

我有反應組件:

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

並且需要將其重構為 2 個單獨的組件,它們將僅渲染 renderDeactivatedMerchant 和 renderActiveMerchant。 所有其他邏輯都應該在這個組件中 FavoritesListItem
所以我以這種方式創建了組件:

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

項目構建沒有錯誤,控制台也沒有錯誤。 但它不會在瀏覽器中呈現這個組件。 我做錯了什么? 請幫忙。

您混淆了 function 和 class 組件的語法,並創建了一個將兩者結合在一起的奇怪混搭:

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

這些道具在 class 中毫無意義:我認為您打算這樣寫:

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

或者

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

就我個人而言,我認為您可以通過共享RenderMerchant和 prop isDeactivated來改進此代碼,而不是使用單獨的組件來激活和停用。 您要避免的兩種情況之間有很多重復的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM