React函数组件与Hook(2)

案例7:

useLayoutEffect: 与useEffect 作用基本相同 控制函数组件生命周期

useLayoutEffect: 执行的时间是在 挂载之前、更新之前 执行

  useLayoutEffect(() => {

    挂载之前、更新之前执行的业务代码

    return () => {

      销毁之前执行的业务代码

    };

  }, [依赖项列表])

Father.jsx:

import {useState, useEffect, useLayoutEffect} from 'react'


  useEffect(() => {
    let start = new Date().getTime();

    // 死循环 造成JS 代码线程阻塞
    while(true){

      let end = new Date().getTime();

      // 如果 超过 2秒中退出循环
      if(end-start >= 1000){
        break;
      }

      if(num === 0){
        setnum(Math.random()); //仅使用测试使用
        console.log('setCount...............num:', num);
      }
    }

   
  }, [num]);*/
  

  useLayoutEffect(() => {

    let start = new Date().getTime();

    // 死循环 造成JS 代码线程阻塞
    while(true){

      let end = new Date().getTime();

      // 如果 超过 2秒中退出循环
      if(end-start >= 1000 ){
       
        break;
      }

      if(num === 0){
        setnum(Math.random());
        console.log('setCount...............num:', num);
      }
    }
    
  },[num]);

  return (
    <div>
      <h1>Father组件: useLayoutEffect</h1>
      <h3 className='h3 text-danger'>num: {num}</h3>
      <button onClick={handleNum}>num随机值</button>
    </div>
  )
}

export default Father

案例八:

useRef : 在函数组件中 创建一个 ref 对象

useImperativeHandle: 在函数组件中将组件内部的属性(变量、状态、 方法) 暴露给直系父组件

注: 要配合 forwardRef 函数使用

  useImperativeHandle(

    函数组件捆绑的ref变量名,

    () => {

      return {

        将函数组件内暴露的属性写在返回值对象中

      }

    },

    [依赖项列表],

  )

Father.jsx:

import {useRef} from 'react';
import Son from './Son';


const Father = () => {

  // 创建一个 ref
  const SonRef = useRef();

  const handleRef = e => {
    console.log('SonRef=>', SonRef);

    SonRef.current.sonupdateTitle(e);

  }

  return (
    <div >
      <h1>Father组件: useRef</h1>
      <button onClick={handleRef}>useRef</button>
      <hr/>
      <Son ref={SonRef}/>
    </div>
  )
}

export default Father

Son.jsx:

import {useState, memo, forwardRef, useImperativeHandle} from 'react'


const Son = (props, sonRef) => {

  const [title, settitle] = useState('Hello Son');

  useImperativeHandle(
    sonRef,
    () => ({
      sonStateTitle: title,
      sonupdateTitle: updateTitle
    }),
    [title],
  )

  const updateTitle = e => {
    settitle(new Date().getTime())
  }

  return (
    <div>
      <h1>Son组件</h1>
      <h3>title:{title}</h3>
      <button onClick={updateTitle}>修改title</button>
    </div>
  )
}

export default memo(forwardRef(Son));

案例九:

useMemo 与 useCallback : 缓存结果

useMemo: 相当于 vue 中计算属性(computed), 缓存计算结果值

  let computedResult = useMemo(

    () => {

      return 计算结果(任意类型)

    },

    [依赖项列表]

  );

computedResult: 返回值  useMemo 函数计算的结果值

依赖项列表: 依赖项列表中任意的一个只发生改变 则会重新执行 useMemo 函数中中第一个参数(函数对象/重新计算)



 

useCallback: 缓存一个函数对象

  let computedFunction = useCallback(

    () => {

      业务代码

    },

    [依赖项],

  )

computedFunction 返回值 : 函数对象类型  就是useCallback函数中的第一个参数对象

useCallback(fn, deps) 相当于 useMemo(() => fn, deps)。

Father.jsx:

import {useState, useMemo} from 'react'


const Father = () => {

  const [msg, setMsg] = useState('Hello');

  let computedResult = useMemo(
    () => {
      console.log('useMemo执行..............');
      return msg+'  '+'abc';
    }, 
    [msg]
  );


  const handleMsg = e=> {
    setMsg(new Date().getTime());
  }


  return (
    <div>
      <h1>Father组件: useMemo</h1>
      <h3>msg: {msg}</h3>
      <h3>useMemo1: {computedResult}</h3>
      <h3>useMemo2: {computedResult}</h3>
      <h3>useMemo3: {computedResult}</h3>
      <button onClick={handleMsg}>msg</button>
    </div>
  )
}

export default Father

Father1.jsx:

import {useState,useCallback, useEffect} from 'react'

const Father1 = () => {

  const [slot, setslot] = useState(()=>(<h1>初始Slot</h1>));
  const [count, setcount] = useState(0)

  let computedFunction = useCallback(
    () => {
      return (<h3>useCallback Hook函数  {count}</h3>)
    },
    []
  )

  useEffect(() => {
    console.log('执行useEffect........');
   
  }, [computedFunction])
  

  

  const changSlot = ()=>{
    let temp = computedFunction();
    setslot(temp);
  }
  

  return (
    <div>
      <h1>Father1组件: useCallback</h1>
      <h3>count:{count}</h3>
      <button onClick={changSlot}>点击</button>
      <button onClick={e=>setcount(count+1)}>修改count值</button>
      <hr/>
      <div>
        slot:{slot}
      </div>
    </div>
  )
}

export default Father1

案例十

Father.jsx

import { useReducer } from 'react';
import reducer from './reducer';
/* 
useReducer
*/
const mystate = { count: 0  };


const Father = () => {

  const [state, dispatch] = useReducer(reducer, mystate);

  const add = num => {
    dispatch({type: 'add', count: 1});
  }

  const minus = num => {
    dispatch({type: 'minus', count: 1});
  }

  return (
    <div>
      <h1>Father组件: useReducer</h1>
      <h3>count: {state.count}</h3>
      <button onClick={e=>add(1)}>+1</button>
      <button onClick={e=>minus(1)}>-1</button>
    </div>
  )
}

export default Father

recuder.js


const reducer = (state, action) => {
  switch (action.type) {
    case 'add':
      return {...state, count: state.count + action.count};
    case 'minus':
      return {...state, count: state.count - action.count};
  
    default:
      return state;
  }
}

export default reducer;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值