最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

1. 簡介

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

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

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

使用hook限制:

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

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

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

2. useState使用

概述:

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

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

語法:

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

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

使用:

import React, { useState } from 'react';
const App = () => {
  // 相當于在App函數(shù)組件是定義一個state數(shù)據(jù),變量名為 count,修改此count的值的方法為setCount
  // 寫法1:值
  // let [count, setCount] = useState(100)
  // 有的時候,在項目中的初始數(shù)據(jù),要經(jīng)過一系列的運算才能出來的初始值,這時候就可以使用函數(shù)的寫法
  // 寫法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ā)處理 -- 推薦寫法,這樣寫數(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完成表單項自定義hook函數(shù):

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

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 部分的代碼太過復雜,我們可以使用自定義 hook 函數(shù)來簡化這部分的代碼:

import React, { useState } from 'react';
// 在react中,定義的函數(shù)是以use開頭,則認為它就是一個自定義hook函數(shù)
// 在自定義hook函數(shù)中,可以調用內(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ù)拆分到另一個文件中:

useInput.js:

import { useState } from 'react';
// 在react中,定義的函數(shù)是以use開頭,則認為它就是一個自定義hook函數(shù)
// 在自定義hook函數(shù)中,可以調用內(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ù)組件對于在一些生命周期中操作還是無能為力,所以 React 提供了 useEffect 來幫助開發(fā)者處理函數(shù)組件,來幫助模擬完成一部份的開發(fā)中非常常用的生命周期方法。常被別的稱為:副作用處理函數(shù)。此函數(shù)的操作是異步的。

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

注意:useEffect中不能有返回值,React它要自動回收

比如說下面這種場景,我們希望 console.log 函數(shù)中的內(nèi)容只打印一次,但是每當試圖更新的時候,console.log 都會重新執(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;

這時候我們就可以使用 useEffect 函數(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(可以調用多次)
  useEffect(() => {
    console.log('App -- useEffect');
  })
  return (
    <div>
      <h3>App組件 --- {count}</h3>
      <button onClick={addCount}>++++</button>
    </div>
  );
}
export default App;

模擬:componentDidMount(這種寫法可以模擬網(wǎng)絡請求)

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

利用依賴項,模擬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àn)相同的功能
  // let [count, setCount] = useState({ num: 100 })
  // const addCount = () => setCount({ num: count.num + 1 })
  // const addCount = () => setCount(v => ({ num: v.num + 1 }))
  // 參數(shù)2中依賴項,進行填值,只要依賴項中的值,發(fā)生改變,則進行觸發(fā)
  // componentDidMount componentDidUpdate
  useEffect(() => {
    console.log('App -- useEffect');
  // 這里的依賴項中只填了count,所以只有count發(fā)生改變,才會觸發(fā)當前函數(shù)
  }, [count])
  // 對依賴項的使用,可以像下面這樣分開寫,也可以寫在同一個數(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;

有依賴項,模擬: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)
  // 有依賴項,只要count改變,則觸發(fā)
  // componentDidMount componentDidUpdate componentWillUnmout
  useEffect(() => {
    console.log('App -- useEffect');
    // 返回回調函數(shù)中就是 componetWillUnMount
	// 在執(zhí)行下一個 effect 之前,上一個 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)絡請求

import React, { useState, useEffect } from 'react';
import { get } from '@/utils/http'
const App = () => {
  let [films, setFilms] = useState([])
  // useEffect 
  // 在之前的版本:第1個參數(shù)要求只能是一個普通的函數(shù),沒有返回對象,可以返回回調函數(shù),回調函數(shù)它模擬生命周期componentWillUnmout
  // 還有最后一個問題。在代碼中,我們使用async / await從第三方API獲取數(shù)據(jù)。如果你對async/await熟悉的話,你會知道,每個async函數(shù)都會默認返回一個隱式的promise。但是,useEffect不應該返回任何內(nè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)絡請求:

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)絡請求時,實現(xiàn)分頁:

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()
      }}>下一頁</button>
    </div >
  );
}
export default App;

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

相關文章

  • webpack4 + react 搭建多頁面應用示例

    webpack4 + react 搭建多頁面應用示例

    這篇文章主要介紹了webpack4 + react 搭建多頁面應用示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • React服務端渲染原理解析與實踐

    React服務端渲染原理解析與實踐

    這篇文章主要介紹了React服務端渲染原理解析與實踐,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • React?Hooks鉤子中API的使用示例分析

    React?Hooks鉤子中API的使用示例分析

    在react類組件(class)寫法中,有setState和生命周期對狀態(tài)進行管理,但是在函數(shù)組件中不存在這些,故引入hooks(版本:>=16.8),使開發(fā)者在非class的情況下使用更多react特性
    2022-08-08
  • 在React框架中實現(xiàn)一些AngularJS中ng指令的例子

    在React框架中實現(xiàn)一些AngularJS中ng指令的例子

    這篇文章主要介紹了在JavaScript的React框架中實現(xiàn)一些AngularJS指令的例子,React使用Virtual DOM因而與普通的js框架有些不同,需要的朋友可以參考下
    2016-03-03
  • React復制到剪貼板的示例代碼

    React復制到剪貼板的示例代碼

    本篇文章主要介紹了React復制到剪貼板的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • 使用react和redux構建一個簡單的計數(shù)器

    使用react和redux構建一個簡單的計數(shù)器

    這篇文章主要為大家詳細介紹了如何使用react和redux構建一個簡單的計數(shù)器,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2025-01-01
  • VSCode配置react開發(fā)環(huán)境的步驟

    VSCode配置react開發(fā)環(huán)境的步驟

    本篇文章主要介紹了VSCode配置react開發(fā)環(huán)境的步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • React的Props、生命周期詳解

    React的Props、生命周期詳解

    “Props” 是 React 中用于傳遞數(shù)據(jù)給組件的一種機制,通常作為組件的參數(shù)進行傳遞,在 React 中,props 是只讀的,意味著一旦將數(shù)據(jù)傳遞給組件的 props,組件就不能直接修改這些 props 的值,這篇文章主要介紹了React的Props、生命周期,需要的朋友可以參考下
    2024-06-06
  • react-native 封裝選擇彈出框示例(試用ios&android)

    react-native 封裝選擇彈出框示例(試用ios&android)

    本篇文章主要介紹了react-native 封裝選擇彈出框示例(試用ios&android),具有一定的參考價值,有興趣的可以了解一下
    2017-07-07
  • react native環(huán)境安裝流程

    react native環(huán)境安裝流程

    React Native 是目前流行的跨平臺移動應用開發(fā)框架之一。本文介紹react native環(huán)境安裝流程及遇到問題解決方法,感興趣的朋友一起看看吧
    2021-05-05

最新評論

克东县| 蓝田县| 兴隆县| 贵阳市| 和政县| 盐城市| SHOW| 通河县| 明光市| 故城县| 清徐县| 旬阳县| 平塘县| 浮梁县| 怀宁县| 金寨县| 两当县| 乡城县| 宝应县| 天水市| 皮山县| 洪雅县| 神池县| 武宁县| 三台县| 阿拉善左旗| 嘉禾县| 通州区| 浦江县| 惠州市| 遂溪县| 开阳县| 浏阳市| 留坝县| 边坝县| 合水县| 红原县| 犍为县| 新密市| 仪陇县| 无为县|