前端开发之:React Hooks-副作用函数 useEffect

副作用函数 (useEffect)

执行顺序 useState=>render=>useEffect,建立真实的DOM树之后(即浏览器渲染完成页面之后)开始调用

  1. 什么是副作用?
    react 副作用主要作用是:React组件与React之外的第三方系统数据同步,例如:发送分析日志、服务器请求或者用React状态控制非React组件等等;是由React组件的渲染结束触发的。
// 常用场景
// 一、浏览器Api
//// react组件渲染完成后向其他组件发送消息(window.postMessage)
//// video组件渲染结束后,播放视频(video.play)
// 二、请求服务器数据(网络请求)
// 三、渲染其他非React的组件(第三方)

// 使用技巧
// 一、只在React组件第一次渲染完成后执行一次
//// 将依赖传入一个空数组 useEffect(()=>{}, [])
// 二、useEffect的依赖数组触发执行
//// 当传入多个依赖项时:组件初始渲染完成会触发一次执行,同时a,b,c其中一个发生改变都会触发useEffect的一次执行  useEffect(()=>{}, [a,b,c])
// 三、每次组件渲染完成都会执行
//// 不传入依赖项 useEffect(()=>{})
// 四、useEffect中不支持异步操作
//// async/await 不支持 
//// useEffect(async()=>{
////   const a = await postApi()
////   console.log(a) // 不会打印 postApi 返回的数据
//// }, [])
// 五、useEffect在再次执行前会调用上次清理函数(cleanup)
//// 注意在组件卸载时清理一些连接,如事件监听window.removeEventListener。
//// 为此,react在开发环境中,组件在挂载完成后会立即再执行一次挂载,此时,useEffect会在初始挂载执行2次,方便开发调试。如果想屏蔽此效果,可通过清理函数实现。
// 六、可用计算修改组件渲染的数据,不用useEffect处理
/* good 
  const [A, setA] = useState(1)
  const [B, setB] = useState(0)
  // good
  const C = A + B // 可自动触发组件的更新,且效率高
  return (
    <>
      ...
      <div>{C}</div> 
    </>
  )
*/
/* bad 
  const [A, setA] = useState(1)
  const [B, setB] = useState(0)
  const [C, setC] = useState(0) // 没必要
  // bad
    useEffect(()=>{setC(A+B)}, [A,B])
    ....
  return (
    <>
      ...
      <div>{C}</div> 
    </>
  )
*/
// 七、如需要初始化数据,可通过在父组件中给组件添加key自动组件初始化
/* 
  // 父组件
  return (
    <>
      <ChildComponent changeData={pid} key={pid} />
    </>
  )
  // 子组件
  const ChildComponent=({changeData})=>{
    const [params, paramsSet] = useState('')
    // 当changeData改变时,组件的params 自动更新
  }
*/
// 八、当传入的数据是个数组或对象时,避免使用副作用,用直接比较触发重新渲染
//// 1. 数组数据
/* 
  good
  const ChildComponent=({items=[]})=>{
    const [A, setA] = useState(1)
    const [B, setB] = useState(null)
    const [prevItems, prevItemsSet] = useState(items)
    // 直接判断处理数据state,state变化后自动触发组件渲染
    if(prevItems !== items){
      prevItemsSet(items)
      setB(null)
    }
  }
*/
/* 
  bad
  const ChildComponent=({items=[]})=>{
    const [A, setA] = useState(1)
    const [B, setB] = useState(null)
    // 
    useEffect(()=>{
      setB(null) // 会引起不必要的重新渲染流程
    }, [items])
  }
*/
//// 对象中的数据更新
/* good
  const ChildComponent=({configs={},changeConfigs=()=>{}})=>{
    // 包装一个函数,让组件中的事件触发嵌套调用
    const resetSome=(changes)=>{
      changeConfigs(changes)
      moreSetFun(configs.line) 
    }
    // 修改事件嵌套调用 resetSome
    const handleChanges=(changes)=>{
      resetSome(changes)
    }

  }
*/
/* bad
   const ChildComponent=({configs={},changeConfigs=()=>{}})=>{
    // 没必要 会引起没必要的bug, 引起页面多次渲染相同数据
    useEffect(()=>{
      if(configs.line){
        moreSetFun(configs.line) 
      }
    }, [configs])
    // 修改事件嵌套调用 resetSome
    const handleChanges=(changes)=>{
      resetSome(changes)
    }

  }
*/
// 九、事件监听最佳选择也不是useEffect, 可用订阅hook替代
/* 
  function subscribe (cb){
    window.addEventListener(event, cb)
    return ()=>{
      window.removeEventListener(event, cb)
    }
  }
  function useSubscribe(){
    // React hook 可用于订阅其他状态
    return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot?)
  }

  const ChildComponent = ()=>{
    const sub = useSubscribe()
  }

*/
  1. 相当于类组件中的componentDidMountcomponentDidUpdate之后的回调
暂无评论

发送评论 编辑评论

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇