别着急用rudex,FC& React Hooks可能更香

260 阅读2分钟

背景

得到需求要做一个电商平台SKU(商品)数据展示的app,sku有几个属性维度,比如所属仓库(fc),关心的数据日期区间(dateRange)等, 类似下图的设计

image.png

其中page 1,2,3点击后分别对应不同的数据块,可能是仓储水平,历史订单等各种业务数据

目标

如何优雅的设计state来实现这个需求,并且快速交付

可选方案

这个app中的仓库,商品,日期是全局的,会在各个组件中使用,针对这种情况,有两种可能的方法:

  1. 使用redux,把商品,日期,仓库放到container级别的state里,修改通过reducer,state修改后再通过props传达到各个子组件中
  2. 使用react hooks和function component

实现

方案1代码比较繁复,这个业务场景虽然看真实设计图好像很复杂,但是梳理之后是比较清晰的,并不是非用redux不可的场景,而且redux中异步读取数据还需要redux-saga等包的协同,开发效率不高。因此最终选择了方案2

最外层container中用react hooks声明全局state

  const [fc, setFc] = useState('仓库');
  const [sku, setSku] = useState('商品');
  const [tab, setTab] = useState('数据块');
  const [dates, setDates] = useState([moment().add(-7, 'days'), moment()]);

一个或多个参数选择组件,接收这些属性作为props,并且把hook的修改方法作为props修改的回调传入

   <Select
          showSearch
          placeholder="Select FC"
          defaultValue={props.fc}
          optionFilterProp="children"
          onChange={props.setFc} // 通过props传入的set方法设置上层组件的state
        >

数据块组件接收这些属性作为props,读取数据

// container组件调用数据组件
        <DataComponent
          sku={sku}
          fc={fc}
          tab={tab}
          changeFC={setFc}
          changeSku={setSku}
          changeTab={setTab}
        ></DataComponent>
 //数据组件设计,主要是读取数据
 const DataComponent = (props)=>{
  useEffect(() => {
    const fetchData = async (url, setFunc) => {
      const result = await request(url);
      setFunc(result);
    };
    fetchData(`url&{parameter}`, setMasterData);
  }, [props.sku]);//监听全局变量的修改,改变时重新读取数据
 }

总结

这样就可以很清晰的完成整个app的实现了,优点有:

  1. 代码清晰易于维护
  2. 对每个数据块组件,可以很好的控制数据读取和渲染,只有该数据块关心的数据发生变化时才刷新(通过useEffect的第二个参数控制)