前端实习周记12

243 阅读3分钟

前端实习周记12

最后一周的实习,主要把我之前写的页面根据需求又继续完善了不少,忙碌了几天,但是也学到了很多

组件传递对象及相应点击事件修改

需求:原本的业务实现是,点击右侧多选树形列表,将被点击的公司ID传递给左侧统一发请求的组件,现在需要点击获取公司ID及公司名称并传递给发请求的组件和展示echarts图的组件(legend根据是否多选显示公司名称)

实现:

  1. 列表组件中的state:包含每一个被点击公司ID的数组=》每一个被点击的公司ID及公司名组成的对象而形成的数组

    const [selectContent, setSelectContent] = useState([])
    //更新树形结构状态
     setSelectContent([{
          entId: treeData[0] && treeData[0].children[0].entId,
          entName: treeData[0] && treeData[0].children[0].title
        }]);
    //树形结构选择
    const onSelect=(keys,info)=>{
        if(!info.node.children){//处于树形结构最后一层
        //数组不为空逻辑修改
        
        const notNull=selectedContent.some(item=>{
            return item.entId==info.node.entId
          })
          
        if(notNull && selectedContent.length!==1){        selectedContent=selectContent.filter(item=>item.entId !== info.node.entId)
    else if                                  (selectedContent.length < 2 && !notNUll) {
            selectedContent.push({
              entId: info.node.entId,
              entName: info.node.title
            })
     
        }
            
        }
    }
    
  2. 接口请求参数变化

    //原先
    const rankData= await getRank({
        ent_id:entId[0]
    })
    //现在
    const rankData=await getRank{
        ent_id:entValue[0].entId
    }
    

Set取两个数组的交集

需求: 当从树形结构选择列表时,选择主企业时只展示主企业的设备类型,选择主副企业时,展示两个企业的交集

实现:

const [devType, setDevType] = useState([])
​
 //处理主副企业设备类型交集
  const convertDevType=(pre,cur)=>{
    if(entValue?.length===1){
      setDevType([])
    }
    let arrSet=new Set([...pre,...cur])
    setDevType([...arrSet])
  }
​
  //获取完接口数据后
  setData(data)
  convertDevType(devType,data.dev_type)
​

多个请求优化

一个页面同时发送多个请求,使用promise.all优化

const getData = async ()=>{
    const promises=[
        getxxx({...}),
        getxxx({...}),
        getxxx({...}),
                
    ]
    const [xxdata,xxdata,xxdata]=await promise.all(promises)
    
    setxxData(xxdata)...
}

ECharts根据点击数据判断展示

需求:当用户点选中一个企业时,只展示一条折线,当用户选中两个企业时,展示两条折线

实现:

根据原本页面逻辑,先在组件外提前设置好option,在组件内根据接口获取到的数据再对option进行更新,这里主要修改的是更新option的部分,主要对list进行修改

由于后端接口每次只能传递一个企业id获取到一个企业的数据,所以我打算使用state将当用户只点选了一个企业时,将该企业的数据存到组件的state中;当后续用户点击了两个企业时,第一条展示的数据就是原先存储的数据

const [preList, setPreList] = useState([]); 
​
const list = []
    if (devName) {
      if (entValue.length === 1) {
        list.push({
          name: `${devName}: ${entValue[0].entName}`,
          data: entData.data_info[devName]
        })
        setPreList(entData.data_info[devName])
      } else {
        list.push({
          name: `${devName}: ${entValue[0].entName}`,
          data: preList //state中之前存储的数据
        })
​
        list.push({
          name: `${devName}: ${entValue[1].entName}`,
          data: entData.data_info[devName]
        })
      }
​
    }
    

按照这个逻辑写应该是没有问题,但是在测试的时候发现preList只有一次获取到了数据,当展现两条数据时,preList为初始化的值,经过排查发现是因为当用户点击选择了两个企业时,页面重新刷新导致state默认为初始化的数值 ,解决方法:将state写到该组件的父组件当中,通过props传递

本地缓存列表逻辑优化

在修改多选复选逻辑的时候,发现自己写的获取列表进行缓存的逻辑有些不太完善,修改:

//获取列表请求
const getEntData = async (entName, localName, tap) => {
    const entDataList = localStorage.getItem(localName)
    let pretreeData 
    if (entDataList) {//之前已有本地缓存
      const res = JSON.parse(entDataList)
      pretreeData = generateTree(res)
    }//无本地缓存
    const res = await getEnterpriseData({
      group_by: tap,
      ent_name: entName
    })
    if (entDataList !== JSON.stringify(res)) {//本地缓存与接口返回不一致
      const treedata = generateTree(res)
      updateTreeData(treedata)
      localStorage.setItem(localName, JSON.stringify(res))
       return
    }
    //本地缓存与接口返回一致
    updateTreeData(pretreeData)
  }
​

useRef存储不会重新引发渲染

在使用useState,如果state更改的时候就会重新引发渲染,目前的需求只是为了存储数据判断获取初次页面加载的数据,并不希望引发多次渲染页面造成不必要的发送请求,所以可以使用useRef来做:

 const initialDev = useRef(null)
​
 useEffect(() => {
    setLoading(true)
    if (entValue) {
      getDevType()
      if(initialDev.current || paramsData.dev_type){
      getData()}
    }
​
  }, [entValue,initialDev.current])
​
const getDevType = async () => {
    if (entValue.length === 1) {
      const res = await getAnalysisDeviceType({
        ent_id: lastEntValue.entId,
      })
      setParamsData(state => ({
        ...state,
        dev_type: res[0].dev_type
      }));
      setDevType(res)
      initialDev.current = res[0].dev_type
    }
  }