React入門--第三天--函式元件

王大錘_code發表於2020-11-14

函式元件

  • 建立方式
  • 沒有state怎麼辦
  • 沒有生命週期怎麼辦
  • useState原理

建立元件

const Hello = (props) => {
  return <div>{props.message}</div>
}

const Hello = props => <div>{props.message}</div>

function Hello(props) {
  return <div>{props.message}</div>
}

函式元件代替class元件

面臨兩個問題

  • 函式元件沒有state
  • 函式元件沒有生命週期

解決
沒有state

  • Hooks API中叫做useState可以解決問題

沒有生命週期

  • Hooks API叫做useEffect可以解決問題

函式元件實現一個+1功能

const App = props => {
  const [n,setN] = useState(0)
  const onClick = () => {
    setN(n+1)
  }
  return (
    <div>
      {n}
      <button onClick={onClick}>+1</button>
    </div>
  )
}

export default App;

用函式元件就簡單很多,沒有放出class元件實現的程式碼,而且函式元件消除了this

函式元件模擬生命週期

useEffect
模擬componentDidMount
useEffect(()=>{console.log('第一次渲染')},[])
模擬componentDidUpdate
useEffect(()=>{console.log('任意屬性變更')})
useEffect(()=>{console.lod('n變了')},[n])
模擬componentWillUnmount
useEffect(()=>{console.log('第一次渲染') return ()=>{console('元件要死了')} })

後面的引數

  • []就是第一次呼叫
  • [n]就是n更新的時候執行,第一次也會執行
  • [n,m]就是n或者m變了就會執行,第一次也會執行
  • 如果是任何一個state(全部變數)變化都執行,那麼[引數]整個這個東西就可以不寫

函式元件的組合起來特別簡單

const x = () => {
  return <div>x</div>
}

const y = () => {
  return <div>y</div>
}

const z = () => {
  return <>
    <x></x>
    <y></y>
  </>
}

函式元件寫起來程式碼少,但是難一點

有一個問題
模擬componentDidUpdate
useEffect(()=>{console.lod('n變了')},[n])
在初始化的時候也會執行,那怎麼才能在只有變化的時候才執行這個程式碼呢,就是第一次不執行

自定義hook

import React, {useState, useEffect } from "react";

const App = props => {
  const [n, setN] = useState(0);
  const onClick = () => {
    setN(n+1);
  };

  const [nUpdateCount, setNUpdateCount] = useState(0)
  useEffect(() => {
    setNUpdateCount(x=>x+1)//這裡x是接受的引數,就是nUpdateCount
  }, [n])//n變了就把計數器加一

  useEffect(()=>{
    if(nUpdateCount > 1) {
      console.log('n變了');
    }
  }, [nUpdateCount])//n變了,計數器就會變化,也就是相當於n變了

  return (
    <div>
      {n}
      <button onClick={onClick}>+1</button>
    </div>
  )
}

export default App;

這樣就實現了這個功能

但是程式碼太雜了,我們可以封裝一個函式

const useX = (n) => {
  const [nUpdateCount, setNUpdateCount] = useState(0)
  useEffect(() => {
    setNUpdateCount(x=>x+1)//這裡x是接受的引數,就是nUpdateCount
  }, [n]);
  return {
    nUpdateCount: nUpdateCount
  }
};

const nUpdateCount = useX(n).nUpdateCount

useEffect(()=>{
    if(nUpdateCount > 1) {
      console.log('n變了');
    }
  }, [nUpdateCount])

然後改成了這這樣

再改

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

  useEffect(()=>{
    if(Count > 1) {
      fn();
    }
  }, [Count, fn])
};

useUpdate(()=>{
  console.log('n變了')
}, n)

就封裝了一個函式useUpdate,和useEffect非常像
也可以直接拆分成一個元件,元件化
函式元件牛逼!!!

相關文章