欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React中hook函數(shù)與useState及useEffect的使用

 更新時(shí)間:2022年10月08日 08:39:26   作者:月光曬了很涼快  
這篇文章主要介紹了React中hook函數(shù)與useState及useEffect的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧

1. 簡(jiǎn)介

在 React 的世界中,有容器組件和 UI 組件之分,在 React Hooks 出現(xiàn)之前,UI 組件我們可以使用函數(shù)組件,無(wú)狀態(tài)組件來(lái)展示 UI,而對(duì)于容器組件,函數(shù)組件就顯得無(wú)能為力,我們依賴于類組件來(lái)獲取數(shù)據(jù),處理數(shù)據(jù),并向下傳遞參數(shù)給 UI 組件進(jìn)行渲染。React在v16.8 的版本中推出了 React Hooks 新特性,Hook是一套工具函數(shù)的集合,它增強(qiáng)了函數(shù)組件的功能,hook不等于函數(shù)組件,所有的hook函數(shù)都是以u(píng)se開(kāi)頭。

使用 React Hooks 相比于從前的類組件有以下幾點(diǎn)好處:

  • 代碼可讀性更強(qiáng),原本同一塊功能的代碼邏輯被拆分在了不同的生命周期函數(shù)中,容易使開(kāi)發(fā)者修改代碼時(shí)不易去查找,通過(guò) React Hooks 可以將功能代碼聚合,方便維護(hù)
  • 組件樹(shù)層級(jí)變淺,在原本的代碼中,我們經(jīng)常使用 HOC/render/Props 等方式來(lái)復(fù)用組件的狀態(tài),增強(qiáng)功能等,無(wú)疑增加了組件樹(shù)層數(shù)及渲染,而在 React Hooks 中,這些功能都可以通過(guò)強(qiáng)大的自定義的 Hooks 來(lái)實(shí)現(xiàn)

使用hook限制:

  • hook 只能用在函數(shù)組件中,class 組件不行
  • 普通函數(shù)不能使用 hook,默認(rèn)只能是函數(shù)組件才能用

例外:普通函數(shù)名稱以 use 開(kāi)頭也可以,(自定義的函數(shù)以 use 開(kāi)頭,稱為自定義 hook)

  • 函數(shù)組件內(nèi)部的函數(shù)也不能使用 hook
  • hook 函數(shù)一定要放在函數(shù)組件的第一層,別放在 if/for 中(塊級(jí)作用域)
  • 要求函數(shù)組件名稱必須首字母大寫(xiě)

2. useState使用

概述:

類組件中有一個(gè)狀態(tài)屬性,可以通過(guò)此特殊屬性完成私有數(shù)據(jù)的操作。操作此 state 數(shù)據(jù)可以觸發(fā)視圖更新(this.setState())。

函數(shù)組件中,從 react16.8 之后,提供一個(gè) hook 函數(shù) useState 方法,它可以模擬出類組件中的狀態(tài)。

語(yǔ)法:

let [變量,函數(shù)] = useState(值|()=>值)

變量就可以得到useState中的值,函數(shù)就可以修改值。值的存儲(chǔ)使用了閉包。

使用:

import React, { useState } from 'react';
const App = () => {
  // 相當(dāng)于在App函數(shù)組件是定義一個(gè)state數(shù)據(jù),變量名為 count,修改此count的值的方法為setCount
  // 寫(xiě)法1:值
  // let [count, setCount] = useState(100)
  // 有的時(shí)候,在項(xiàng)目中的初始數(shù)據(jù),要經(jīng)過(guò)一系列的運(yùn)算才能出來(lái)的初始值,這時(shí)候就可以使用函數(shù)的寫(xiě)法
  // 寫(xiě)法2:函數(shù)
  let [count, setCount] = useState(() => 100)
  const addCount = () => {
    setCount(count + 1)
  }
  return (
    <div>
      <h1>{count}</h1>
      <button onClick={addCount}>++++</button>
    </div>
  );
}
export default App;

處理并發(fā)操作:

import React, { useState } from 'react';
const App = () => {
  let [count, setCount] = useState(() => 100)
  const addCount = () => {
    // 并發(fā)處理數(shù)據(jù)的完整性得不到保證
    // setCount(count + 1)  // 100+1
    // setCount(count + 1)  // 100+1
    // setCount(count + 1)  // 100+1
    // 并發(fā)處理 -- 推薦寫(xiě)法,這樣寫(xiě)數(shù)據(jù)的完整性可靠的
    setCount(v => v + 1)
    setCount(v => v + 1)
    setCount(v => v + 1)
  }
  return (
    <div>
      <h1>{count}</h1>
      <button onClick={addCount}>++++</button>
    </div>
  );
}
export default App;

使用useState完成表單項(xiàng)自定義hook函數(shù):

如果我們有兩個(gè) input 框需要變?yōu)槭芸亟M件,我們可以這樣寫(xiě):

import React, { useState } from 'react';
const App = () => {
  let [username, setUsername] = useState('')
  let [password, setPassword] = useState('')
  return (
    <div>
      {/* 受控組件 */}
      <input type="text" value={username} onChange={e => setUsername(e.target.value)} />
      <input type="text" value={password} onChange={e => setPassword(e.target.value)} />
    </div>
  );
}
export default App;

上面的做法讓 return 部分的代碼太過(guò)復(fù)雜,我們可以使用自定義 hook 函數(shù)來(lái)簡(jiǎn)化這部分的代碼:

import React, { useState } from 'react';
// 在react中,定義的函數(shù)是以u(píng)se開(kāi)頭,則認(rèn)為它就是一個(gè)自定義hook函數(shù)
// 在自定義hook函數(shù)中,可以調(diào)用內(nèi)置hook
function useInput(initialValue = '') {
  let [value, setValue] = useState(initialValue)
  return { value, onChange: e => setValue(e.target.value.trim()) }
}
const App = () => {
  let usernameInput = useInput('')
  let passwordInput = useInput('')
  return (
    <div>
      {/* 受控組件 */}
      <input type="text" {...usernameInput} />
      <input type="text" {...passwordInput} />
    </div>
  );
}
export default App;

我們還可以使用模塊化的思想,將自定義 hook 函數(shù)拆分到另一個(gè)文件中:

useInput.js:

import { useState } from 'react';
// 在react中,定義的函數(shù)是以u(píng)se開(kāi)頭,則認(rèn)為它就是一個(gè)自定義hook函數(shù)
// 在自定義hook函數(shù)中,可以調(diào)用內(nèi)置hook
const useInput = (initialValue = '') => {
  let [value, setValue] = useState(initialValue)
  return { value, onChange: e => setValue(e.target.value.trim()) }
}
export default useInput

App.jsx:

import React from 'react';
import useInput from './hook/useInput';
const App = () => {
  let usernameInput = useInput('')
  let passwordInput = useInput('')
  return (
    <div>
      <input type="text" {...usernameInput} />
      <input type="text" {...passwordInput} />
    </div>
  );
}
export default App;

3. useEffect使用

概述:

此 hook 可以模擬函數(shù)組件的生命周期,函數(shù)組件對(duì)于在一些生命周期中操作還是無(wú)能為力,所以 React 提供了 useEffect 來(lái)幫助開(kāi)發(fā)者處理函數(shù)組件,來(lái)幫助模擬完成一部份的開(kāi)發(fā)中非常常用的生命周期方法。常被別的稱為:副作用處理函數(shù)。此函數(shù)的操作是異步的。

它并不能模擬全部的鉤子函數(shù),它只能模擬下面這幾個(gè):componentDidMount、componentDidUpdate、componentWillUnmout。

注意:useEffect中不能有返回值,React它要自動(dòng)回收

比如說(shuō)下面這種場(chǎng)景,我們希望 console.log 函數(shù)中的內(nèi)容只打印一次,但是每當(dāng)試圖更新的時(shí)候,console.log 都會(huì)重新執(zhí)行:

import React, { useState } from 'react';
const App = () => {
  let [count, setCount] = useState(100)
  const addCount = () => setCount(count + 1)
  console.log('App -- 要求此處只打印一次');
  return (
    <div>
      <h3>App組件 --- {count}</h3>
      <button onClick={addCount}>++++</button>
    </div>
  );
}
export default App;

這時(shí)候我們就可以使用 useEffect 函數(shù)來(lái)實(shí)現(xiàn)上述需求。

使用:

模擬:componentDidMount componentDidUpdate

import React, { useState, useEffect } from 'react';
const App = () => {
  let [count, setCount] = useState(100)
  const addCount = () => setCount(count + 1)
  // 模擬:componentDidMount componentDidUpdate(可以調(diào)用多次)
  useEffect(() => {
    console.log('App -- useEffect');
  })
  return (
    <div>
      <h3>App組件 --- {count}</h3>
      <button onClick={addCount}>++++</button>
    </div>
  );
}
export default App;

模擬:componentDidMount(這種寫(xiě)法可以模擬網(wǎng)絡(luò)請(qǐng)求)

import React, { useState, useEffect } from 'react';
const App = () => {
  let [count, setCount] = useState(100)
  const addCount = () => setCount(count + 1)
  // 模擬:componentDidMount(可以調(diào)用多次)
  // 參數(shù)2:依賴項(xiàng),如果為空數(shù)據(jù),則只執(zhí)行1次
  // 一般在這樣的寫(xiě)法中,完成網(wǎng)絡(luò)請(qǐng)求
  useEffect(() => {
    console.log('App -- useEffect');
  }, [])
  return (
    <div>
      <h3>App組件 --- {count}</h3>
      <button onClick={addCount}>++++</button>
    </div>
  );
}
export default App;

利用依賴項(xiàng),模擬componentDidMount、componentDidUpdate

import React, { useState, useEffect } from 'react';
const App = () => {
  let [count, setCount] = useState(100)
  let [name, setName] = useState('')
  const addCount = () => setCount(count + 1)
  // 下面這種寫(xiě)法,也可以實(shí)現(xiàn)相同的功能
  // let [count, setCount] = useState({ num: 100 })
  // const addCount = () => setCount({ num: count.num + 1 })
  // const addCount = () => setCount(v => ({ num: v.num + 1 }))
  // 參數(shù)2中依賴項(xiàng),進(jìn)行填值,只要依賴項(xiàng)中的值,發(fā)生改變,則進(jìn)行觸發(fā)
  // componentDidMount componentDidUpdate
  useEffect(() => {
    console.log('App -- useEffect');
  // 這里的依賴項(xiàng)中只填了count,所以只有count發(fā)生改變,才會(huì)觸發(fā)當(dāng)前函數(shù)
  }, [count])
  // 對(duì)依賴項(xiàng)的使用,可以像下面這樣分開(kāi)寫(xiě),也可以寫(xiě)在同一個(gè)數(shù)組中
  // useEffect(() => {
  //   console.log('App -- useEffect');
  // }, [name]) 
  return (
    <div>
      <input value={name} onChange={e => setName(e.target.value)} />
      <h3>App組件 --- {count}</h3>
      <button onClick={addCount}>++++</button>
    </div>
  );
}
export default App;

有依賴項(xiàng),模擬:componentDidMount、componentDidUpdate、componentWillUnmout

import React, { useState, useEffect } from 'react';
const App = () => {
  let [count, setCount] = useState(100)
  let [name, setName] = useState('')
  const addCount = () => setCount(count + 1)
  // 有依賴項(xiàng),只要count改變,則觸發(fā)
  // componentDidMount componentDidUpdate componentWillUnmout
  useEffect(() => {
    console.log('App -- useEffect');
    // 返回回調(diào)函數(shù)中就是 componetWillUnMount
	// 在執(zhí)行下一個(gè) effect 之前,上一個(gè) effect 就已被清除
    return () => {
      console.log('componentWillUnmout');
    }
  }, [count])
  return (
    <div>
      <input value={name} onChange={e => setName(e.target.value)} />
      <h3>App組件 --- {count}</h3>
      <button onClick={addCount}>++++</button>
    </div>
  );
}
export default App;

模擬組件銷毀

import React, { useState, useEffect } from 'react';
const App = () => {
  let [count, setCount] = useState(100)
  let [name, setName] = useState('')
  const addCount = () => setCount(count + 1)
  return (
    <div>
      <input value={name} onChange={e => setName(e.target.value)} />
      <h3>App組件 --- {count}</h3>
      {
        count > 103 ? null : <Child />
      }
      <button onClick={addCount}>++++</button>
    </div>
  );
}
function Child() {
  // componentDidMount componentWillUnmout  -- 一般模擬組件的銷毀
  useEffect(() => {
    console.log('child -- componentDidMount');
    return () => {
      console.log('child -- componentWillUnmout');
    }
  }, [])
  return (
    <div>
      <h3>Child</h3>
    </div>
  )
}
export default App;

useEffect發(fā)起網(wǎng)絡(luò)請(qǐng)求

import React, { useState, useEffect } from 'react';
import { get } from '@/utils/http'
const App = () => {
  let [films, setFilms] = useState([])
  // useEffect 
  // 在之前的版本:第1個(gè)參數(shù)要求只能是一個(gè)普通的函數(shù),沒(méi)有返回對(duì)象,可以返回回調(diào)函數(shù),回調(diào)函數(shù)它模擬生命周期componentWillUnmout
  // 還有最后一個(gè)問(wèn)題。在代碼中,我們使用async / await從第三方API獲取數(shù)據(jù)。如果你對(duì)async/await熟悉的話,你會(huì)知道,每個(gè)async函數(shù)都會(huì)默認(rèn)返回一個(gè)隱式的promise。但是,useEffect不應(yīng)該返回任何內(nèi)容。這就是為什么會(huì)在控制臺(tái)日志中看到以下警告:
  // Warning: useEffect function must return a cleanup function or nothing. Promises and useEffect(async () => …) are not supported, but you can call an async function inside an effect
  useEffect(async () => {
    let ret = await get('/api/swiper')
    setFilms(ret.data)
  }, [])
  // 如果useEffect頂層不支持 async/await可以使用如下的解決方案
  /* useEffect(() => {
    ; (async function () {
      let ret = await get('/api/swiper')
      setFilms(ret.data)
    })()
  }, []) */
  return (
    <div>
      <h3>App組件</h3>
      <ul>
        {
          films.map(item => (
            <li key={item.id} > {item.title}</li>
          ))
        }
      </ul>
    </div >
  );
}
export default App;

useEffect 封裝網(wǎng)絡(luò)請(qǐng)求:

useSwiper.js:

import { useEffect, useState } from 'react';
import { get } from '@/utils/http'
const useSwiper = (initialValue = []) => {
  let [data, setData] = useState(initialValue)
  useEffect(async () => {
    let ret = await get('/api/swiper')
    setData(ret.data)
  }, [])
  return data
}
export default useSwiper

App.jsx:

import useSwiper from "./hook/useSwiper";
const App = () => {
  let data = useSwiper()
  return (
    <div>
      <h3>App組件</h3>
      <ul>
        {
          data.map(item => (
            <li key={item.id} > {item.title}</li>
          ))
        }
      </ul>
    </div >
  );
}
export default App;

封裝網(wǎng)絡(luò)請(qǐng)求時(shí),實(shí)現(xiàn)分頁(yè):

useGoodFood.js:

import { useEffect, useState } from 'react';
import { get } from '@/utils/http'
const useGoodFood = (initialValue = []) => {
  let [data, setData] = useState(initialValue)
  let [page, setPage] = useState(1)
  const loadData = async () => {
    let ret = await get('/api/goodfood?page=' + page)
    if (ret.data.length > 0) {
      // setData(v => [...v, ...ret.data])
      setData(ret.data)
      setPage(v => v + 1)
    }
  }
  useEffect(() => {
    loadData()
  }, [])
  return [data, loadData]
}
export default useGoodFood

App.jsx:

import useGoodFood from "./hook/useGoodFood";
const App = () => {
  let [data, loadData] = useGoodFood()
  return (
    <div>
      <h3>App組件</h3>
      <ul>
        {
          data.map(item => (
            <li key={item.id} > {item.name}</li>
          ))
        }
      </ul>
      <hr />
      <button onClick={() => {
        loadData()
      }}>下一頁(yè)</button>
    </div >
  );
}
export default App;

到此這篇關(guān)于React中hook函數(shù)與useState及useEffect的使用的文章就介紹到這了,更多相關(guān)React中hook函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React實(shí)現(xiàn)二級(jí)聯(lián)動(dòng)的方法

    React實(shí)現(xiàn)二級(jí)聯(lián)動(dòng)的方法

    這篇文章主要為大家詳細(xì)介紹了React實(shí)現(xiàn)二級(jí)聯(lián)動(dòng)的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 深入了解React中的合成事件

    深入了解React中的合成事件

    React 中的事件,是對(duì)原生事件的封裝,叫做合成事件。這篇文章主要通過(guò)幾個(gè)簡(jiǎn)單的示例為大家詳細(xì)介紹一下React中的合成事件,感興趣的可以了解一下
    2023-02-02
  • React?中使用?RxJS?優(yōu)化數(shù)據(jù)流的處理方案

    React?中使用?RxJS?優(yōu)化數(shù)據(jù)流的處理方案

    這篇文章主要為大家介紹了React?中使用?RxJS?優(yōu)化數(shù)據(jù)流的處理方案示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • React特征Form?單向數(shù)據(jù)流示例詳解

    React特征Form?單向數(shù)據(jù)流示例詳解

    這篇文章主要為大家介紹了React特征Form?單向數(shù)據(jù)流示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • react實(shí)現(xiàn)無(wú)限循環(huán)滾動(dòng)信息

    react實(shí)現(xiàn)無(wú)限循環(huán)滾動(dòng)信息

    這篇文章主要為大家詳細(xì)介紹了react實(shí)現(xiàn)無(wú)限循環(huán)滾動(dòng)信息,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • react中實(shí)現(xiàn)修改input的defaultValue

    react中實(shí)現(xiàn)修改input的defaultValue

    這篇文章主要介紹了react中實(shí)現(xiàn)修改input的defaultValue方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • React 服務(wù)器組件的使用方法詳解

    React 服務(wù)器組件的使用方法詳解

    最近,React 服務(wù)器組件受到了廣泛的關(guān)注和熱捧,這是因?yàn)?nbsp;React 服務(wù)器組件允許開(kāi)發(fā)人員將與組件相關(guān)的任務(wù)外包給服務(wù)器,在本文中,我們將討論什么是 React 服務(wù)器組件,以及如何將它們集成到構(gòu)建應(yīng)用程序中,需要的朋友可以參考下
    2023-10-10
  • React父子組件間的傳值的方法

    React父子組件間的傳值的方法

    在單頁(yè)面里面,父子組件傳值是比較常見(jiàn)的,這篇文章主要介紹了React父子組件間的傳值的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • React-Native中一些常用組件的用法詳解(一)

    React-Native中一些常用組件的用法詳解(一)

    這篇文章主要跟大家分享了關(guān)于React-Native中一些常用組件的用法,其中包括View組件、Text組件、Touchable類組件、TextInput組件以及Image組件的使用方法,分別給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),需要的朋友們下面來(lái)一起看看吧。
    2017-06-06
  • React插槽使用方法

    React插槽使用方法

    本文主要介紹了React插槽使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12

最新評(píng)論