资讯专栏INFORMATION COLUMN

React组件设计模式(一)

godruoyi / 3058人阅读

摘要:数据放在组件中,作为一个无状态组件,只做他的展示。用两种组件设计模式可以帮助到我们。将处理后的数据作为参数执行,最终返回组件,这就是模式。二高阶组件模式所谓的高阶组件,其实就是一个函数,该接受为参数,返回一个处理后的。

完整代码可查看github,这里截取的代码不影响理解就行。

页面效果可查看gitPage

首先编写一下我们的公共组件

单个商品组件(商品组件:展示价格、购买数量)

goodsItem.js

// 单个商品
import React from "react";
const GoodsItem = props => {
  const { goods: {name, num, price}, handleSub, handleAdd } = props;
  return 
{name} {num} 价格:{price}
}; export default GoodsItem;
商品列表组件(循环展示库中的商品)

goodList.js

// 商品列表

import React from "react";
import GoodsItem from "./goodsItem";
class GoodsList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      goodsData: []
    }
  }
  componentDidMount() {
    const { goodsData } = this.props;
    this.setState({ goodsData: goodsData});
  }
  handleAddorSub(id, type) {
    let { goodsData } = this.state;
    let newGoods = goodsData.reduce((newData, goods) => {
      if (goods.id === id) {
        goods.num = type === "+" ? goods.num + 1 : goods.num - 1;
      }
      newData.push(goods);
      return newData;
    }, [])
    this.setState({ goodsData: newGoods })
  }
  render() {
    const { goodsData } = this.state;
    return (
      
{goodsData.map(goods => this.handleAddorSub(goods.id, "+")} handleSub={() => this.handleAddorSub(goods.id, "-")} /> )}
); } }; export default GoodsList;

我们一般编写组件,都会这么去做,list包裹item,循环展示item。数据放在list组件中,item作为一个无状态组件,只做他的展示。

数据交互通过props传递,点击+-会改变购物车里的数据。

现在需求来了,双12来了(就在昨日),所有商品8折优惠。

这意味着我们需要修改goodsData中所有商品的价格。

这并不难,我叶良辰有100种方法可以修改商品数据。找个可行的生命周期,比如componentDidMount中修改list组件state.goodsData就行了。

如果每次修改都直接修改goodList组件,也是可以的,大不了多传几个props来判断需要打折还是修改商品名称等等。

但是有些需求是交叉的,如果一直这样写,久而久之组件会变得越来越臃肿,最后爆炸。

好的解决方案应该是goodsList不去动他,外加一层来进行包装,实现我们的逻辑。

这样既保证了goodsList的,又能实现逻辑的复用。可谓一箭双雕。

用两种组件设计模式可以帮助到我们。

一. renderProps 模式

renderProps其实是利用组件的props.children api,将函数当成组件的一种写法。

我们调用公共组件的方法如下:

我们用renderProps模式实现打折商品组件:


  {(data) => }

可以看到,DiscountedGoodsList的子组件是一个函数,那么一个函数是怎么渲染成组件的?

再来看看DiscountedGoodsList组件的代码:

const DiscountedGoodsList = props => {
  // 8折优惠逻辑
  const setRenderPropsData = (data) => {
    let renderPropsData = data.reduce((array, goods) => {
      let obj = {};
      for (let k in goods) {
        obj[k] = k === "price" ? (goods[k] * .9).toFixed(2) : goods[k];
      }
      array.push(obj);
      return array;
    }, []);
    return renderPropsData;
  }

  let goodsData = setRenderPropsData(props.goodsData);

  return (
    
      {props.children(goodsData)}
    
  );
}

setRenderPropsData的作用是实现8折优惠逻辑,将所有商品价格调整。

然后调用props.children这个api,得到在上面我们编写的函数。

props.children也就是函数(data) => 的引用。

将处理后的数据goodsData作为参数执行,最终返回组件,这就是renderProps模式。

以后我们需要调用价格优惠的商品列表组件,直接调用DiscountedGoodsList即可。

renderProps的模式实现了逻辑的共用,且对GoodsList组件毫无副作用,从而达到我们的目的。

二. HOC(高阶组件)模式

所谓的高阶组件,其实就是一个函数,该接受component为参数,返回一个处理后的component。

编写我们的高阶组件如下:

const BrandGoodsList = (Component, goodsData) => {
  // 8折优惠逻辑
  const setRenderPropsData = (data) => {
    let renderPropsData = data.reduce((array, goods) => {
      let obj = {};
      for (let k in goods) {
        obj[k] = k === "name" ? goods[k] + "【品牌】" : goods[k];
      }
      array.push(obj);
      return array;
    }, []);
    return renderPropsData;
  }

  let brandGoodsData = setRenderPropsData(goodsData);
  return 
}

BrandGoodsList组件的逻辑就是给商品名称加上【品牌】的标示,区分商品。

高阶组件的调用比较简单:{BrandGoodsList(GoodsList, goodsData)} 直接执行返回组件,然后渲染。

实现了两种模式,现在我们将他们一起用,实现一个既打折,又是品牌商品的组件。


  {(data) => BrandGoodsList(GoodsList, data)}

挺舒服的吧,随时分离,随时结合。正是高内聚、低耦合本人啊。

最后,完整的调用看一下:

基本商品列表组件:
打8折商品列表组件(renderProps模式实现): {(data) => }
品牌商品列表组件(高阶组件模式实现): {BrandGoodsList(GoodsList, goodsData)}
既是打折商品,又是品牌商品(两种模式复用) {(data) => BrandGoodsList(GoodsList, data)}
总结: 1、renderProps 模式的核心是props.children的使用。 2、高阶组件的写法看起来更舒服,比较受欢迎。 3、两种模式解决的问题:复用逻辑、不污染底层组件。

觉得有帮助的点个赞,甚至可以关注一波哦~

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100024.html

相关文章

  • React 设计模式和场景分析

    摘要:这一周连续发表了两篇关于的文章组件复用那些事儿实现按需加载轮子应用设计之道化妙用其中涉及到组件复用轮子设计相关话题,并配合相关场景实例进行了分析。 showImg(https://segmentfault.com/img/remote/1460000014482098); 这一周连续发表了两篇关于 React 的文章: 组件复用那些事儿 - React 实现按需加载轮子 React ...

    avwu 评论0 收藏0
  • React 设计模式和场景分析

    摘要:这一周连续发表了两篇关于的文章组件复用那些事儿实现按需加载轮子应用设计之道化妙用其中涉及到组件复用轮子设计相关话题,并配合相关场景实例进行了分析。 showImg(https://segmentfault.com/img/remote/1460000014482098); 这一周连续发表了两篇关于 React 的文章: 组件复用那些事儿 - React 实现按需加载轮子 React ...

    sshe 评论0 收藏0
  • React 深入系列7:React 常用模式

    摘要:本篇是深入系列的最后一篇,将介绍开发应用时,经常用到的模式,这些模式并非都有官方名称,所以有些模式的命名并不一定准确,请读者主要关注模式的内容。 React 深入系列,深入讲解了React中的重点概念、特性和模式等,旨在帮助大家加深对React的理解,以及在项目中更加灵活地使用React。 本篇是React深入系列的最后一篇,将介绍开发React应用时,经常用到的模式,这些模式并非都有...

    Chao 评论0 收藏0
  • 精益 React 学习指南 (Lean React)- 4.2 react patterns

    摘要:另外一点是组件应该尽量保证独立性,避免和外部的耦合,使用全局事件造成了和外部事件的耦合。明确的职责分配也增加了应用的确定性明确只有组件能够知道状态数据,且是对应部分的数据。 书籍完整目录 4.2 react patterns 修改 Props Immutable data representation 确定性 在 getInitialState 中使用 props 私有状态和...

    Berwin 评论0 收藏0
  • React组件模型启示录

    摘要:另一种关于组件的常见说法,是组件是为了重用。这件事情是前端特有的,受限制于的结构。这一节的题目叫做混乱的组件通讯,我们来仔细掰扯一下细节,因为组件模型虽然很常说但是对通讯过程没有约定。 这个话题很难写。 但是反过来说,爱因斯坦有句名言:如果你不能把一个问题向一个六岁孩子解释清楚,那么你不真的明白它。 所以解释清楚一个问题的关键,不是去扩大化,而是相反,最小化。 Lets begin. ...

    eternalshallow 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<