函数式组件useState中state更新问题和useEffect模拟生命周期

全貌:

//1.引入useEffect, useState
import React, { useEffect, useState } from 'react';
import HeaderScreening from 'components/IDBHeaderScreening';

import {
  SetLCollect
} from '../../newServices';

import Chart from '../Chart';

import './index.less';
import { func } from 'prop-types';


const PageView = ({

  filterReady,
  filterChange,
  save,
  onFilterChange,
  onFilterReady,
  ...props
}) => {
//2.
  const [lineData, setLineData] = React.useState(undefined);
  
  const fetchDatas = () => {
    fetchLineChartData();
    fetchCommentChartData();
  };

  //
  const fetchLineChartData = () => {
//3.
    SetLCollect().then(res => setLineData(res.data.result));
  };
  useEffect(() => {
    fetchDatas();
  }, []);

  return (
    <div className="yt_productAnalysis_aspectAnalysis_wrapper">
      <HeaderScreening
        onReady={onFilterReady}
        onChange={onFilterChange}
        pageType="ASPECT_TREND" // SOCIAL_OVERVIEW
        // noSavingFilterList={true}
        advanceAuthority={false}
        valueConf={['fullInfo']}
        showList={['fullDate', 'screening', 'save']}
        hasHour={true}
      >
        <div className="content">
        //4.
          <Chart data={lineData} />
         
        </div>
      </HeaderScreening>
    </div>
  );
};

export default PageView;

 

一。1..基本使用:[state,setState]=useState(0);    eg:

const [lineData, setLineData] = React.useState(undefined);

   2. 通过setState更新state,eg:

 setLineData(res.data.result)
3.因为
etLineData(res.data.result)是在异步中进行处理的,所以
lineData在初次渲染的时候还是undefined;
只用在子组件
 <Chart data={lineData} />
渲染的时候才能获取到更新之后的数据
<Chart/>组件详情
import React from 'react';

//,测试mock数据的state获取
export default props => {
  //   console.log(props, '1232142445');
  return <div>123</div>;
};

 

 

二.生命周期的模拟(以下转载自:https://www.cnblogs.com/lovevin/p/13231718.html)

4. 函数组件模拟生命周期

函数组件同样地没有生命周期,但是 React Hooks API 提供了 React.useEffect 来解决此问题。

React.useEffect(fn, ??) 第一个参数是在特定时机到的时候执行的回调函数,第二个参数是指明什么时机。

4.1 模拟 componentDidMount 第一次渲染

在第二个参数为 [] 时只会在第一次渲染时执行

useEffect(()=>{
      console.log("第一次渲染");
},[])

4.2 模拟 componentDidUpdate (不完全模拟)

在第二个参数的数组里加上要监听变化的数据就行,若不加数组,不传第二个参数,则会在 state 的任意一个属性改变时都会触发该函数回调

useEffect(()=>{
      console.log("n 变了");
},[n])
useEffect(()=>{
      console.log("任意属性变了");
})

但是这样的模拟并不完全等同,因为该函数回调会在一开始在数据由未定义 undefined 到被赋值后会执行该回调函数。而 componentDidUpdate 不会再第一次渲染时执行。

因此可以 自定义 Hook 进行计数,正确模拟 componentDidUpdate 钩子,自定义 useUpdate.js 如下:

const useUpdate = (fn, dep)=>{
      const [count,setCount] = useState(0)
      useEffect(()=>{
            setCount(x => x + 1);
      },[dep])
      useEffect(()=>{
            if(count > 1){
                  fn()
            }
      },[count,fn])
}

4.3 模拟 componentWillUnmount

模拟销毁前执行时期,是用函数里返回函数的方式。

useEffect(()=>{
      console.log("任意属性变了");
      return ()=>{
            console.log("该组件要销毁了")
      }
})



上一篇:React 手写 自定义hooks 倒计时事件 通用逻辑的封装


下一篇:useContext简单使用笔记