React教程:4 個 useState Hook 示例

来源:https://www.cnblogs.com/fundebug/archive/2019/08/22/4-react-usestate-hook-examples.html
-Advertisement-
Play Games

摘要: React示例教程。 原文: "快速瞭解 React Hooks 原理" 譯者:前端小智 到 React 16.8 目前為止,如果編寫函數組件,然後遇到需要添加狀態的情況,咱們就必須將組件轉換為類組件。 編寫 ,將函數體複製到 方法中,修複縮進,最後添加需要的狀態。 今天,可以使用 Hook ...


摘要: React示例教程。

到 React 16.8 目前為止,如果編寫函數組件,然後遇到需要添加狀態的情況,咱們就必須將組件轉換為類組件。

編寫 class Thing extends React.Component,將函數體複製到render()方法中,修複縮進,最後添加需要的狀態。

今天,可以使用 Hook 獲得相同的功能,併為自己節省了工作時間。在本文中,主要介紹useState hook。

useState 做啥子的

useState hook 允許咱們向函數組件添加狀態,我們通常稱這些為“ hooks”,但它們實際上是函數,與 React 16.8 捆綁在一起。 通過在函數組件中調用useState,就會創建一個單獨的狀態。

在類組件中,state 總是一個對象,可以在該對象上添加保存屬性。

對於 hooks,state 不必是對象,它可以是你想要的任何類型-數組、數字、布爾值、字元串等等。每次調用useState都會創建一個state塊,其中包含一個值。

示例1:使用 useState 顯示/隱藏組件

這個示例是一個組件,它顯示一些文本,併在末尾顯示一個read more鏈接,當單擊鏈接時,它展開剩下的文本。

    import React, { useState } from 'react';
    import ReactDOM from 'react-dom';
    
    // 兩個 props:
    //   text - 顯示的內容
    //   maxLength - 在點擊“read more”之前顯示多少個字元
    function LessText({ text, maxLength }) {
      // 創建一個狀態,並將其初始化為“true”
      const [hidden, setHidden] = useState(true);
    

      if (text <= maxLength) {
        return <span>{text}</span>;
      }
    
      return (
        <span>
          {hidden ? `${text.substr(0, maxLength).trim()} ...` : text}
          {hidden ? (
            <a onClick={() => setHidden(false)}> read more</a>
          ) : (
            <a onClick={() => setHidden(true)}> read less</a>
          )}
        </span>
      );
    }
    
    ReactDOM.render(
      <LessText
        text={`專註、努力是成功的真正關鍵。把你的眼睛盯在目標上,然後朝著目標邁出下一步`}
        maxLength={35}
      />,
      document.querySelector('#root')
    );

僅用一行代碼,我們就使這個函數組件有狀態:

    const [hidden, setHidden] = useState(true);

但是這個函數到底在做什麼呢?如果每次渲染都調用它(確實如此),它又是如何保留狀態的。

Hooks 實現的技巧

這裡的“神奇”之處是,React在每個組件的幕後維護一個對象,並且在這個持久對象中,有一個“狀態單元”數組。當你調用useState時,React將該狀態存儲在下一個可用的單元格中,並遞增數組索引。

假設你的 hooks 總是以相同的順序調用(如果遵循 hooks 的規則,它們將是相同的順序),React能夠查找特定useState調用的前一個值。對useState的第一個調用存儲在第一個數組元素中,第二個調用存儲在第二個元素中,依此類推。

這也不是很神奇的事情,主要它依賴於你可能沒有想過的事實:咱們寫的的組件是由React調用 ,所以它可以在調用組件之前事先做好一些工作。 而且,渲染組件的行為不僅僅是函數調用。 像<Thing />這樣的JSX被編譯為React.createElement(Thing) - 顯然 React 可以控制它的調用方式和時間。

示例2:根據之前的狀態更新狀態

看看另一個例子:根據前一個值更新state的值。

咱們要造個計步器,每點擊一次按鈕,就計一次,點擊完後,它會告訴你你走了多少步。

    import React, { useState } from 'react';
    
    function StepTracker() {
      const [steps, setSteps] = useState(0);
    
      function increment() {
        setSteps(steps => steps + 1);
      }
    
      return (
        <div>
          總共走了 {steps} 步!
          <br />
          <button onClick={increment}>
            點點我,步數不是個事!
          </button>
        </div>
      );
    }
    
    ReactDOM.render(
      <StepTracker />,
      document.querySelector('#root')
    );

首先,通過調用useState創建一個新的state,並將其初始化為0。它返回steps的當前值0setSteps函數來更新 steps,用 increment函數來對steps進行增 1 操作。

這裡還可以優化的提取increment函數,可以直接將 increment 函數裡面的內聯到 onClick 裡面:

    <button onClick={() => setSteps(steps => steps + 1)}>
      I took another step
    </button>

示例3: state 作為數組

記住,state可以保存任何你想要的值。下麵是一個隨機數列表的例子,單擊按鈕將向列表添加一個新的隨機數:

    function RandomList() {
      const [items, setItems] = useState([]);
    
      const addItem = () => {
        setItems([
          ...items,
          {
            id: items.length,
            value: Math.random() * 100
          }
        ]);
      };
    
      return (
        <>
          <button onClick={addItem}>Add a number</button>
          <ul>
            {items.map(item => (
              <li key={item.id}>{item.value}</li>
            ))}
          </ul>
        </>
      );
    }

註意,我們state初始化為空數組[],併在addItem函數中更新值。

setItems 更新 state 不會將舊值“合併” - 它會使用新值覆蓋state。 這與this.setState在類中的工作方式不同。

示例4:具有多個鍵的 state

再來看看,state為對象的例子,創建一個包含2個欄位的登錄表單:usernamepassword

下麵示例主要展示如何在一個state對象中存儲多個值,以及如何更新單個值。

    function LoginForm() {
      const [form, setValues] = useState({
        username: '',
        password: ''
      });
    
      const printValues = e => {
        e.preventDefault();
        console.log(form.username, form.password);
      };
    
      const updateField = e => {
        setValues({
          ...form,
          [e.target.name]: e.target.value
        });
      };
    
      return (
        <form onSubmit={printValues}>
          <label>
            Username:
            <input
              value={form.username}
              name="username"
              onChange={updateField}
            />
          </label>
          <br />
          <label>
            Password:
            <input
              value={form.password}
              name="password"
              type="password"
              onChange={updateField}
            />
          </label>
          <br />
          <button>Submit</button>
        </form>
      );
    }

如果想試試,可查看 CodeSandbox

首先,我們創建一個state片段,並用一個對象初始化它

    const [form, setValues] = useState({
      username: '',
      password: ''
    })

這看起來像是在類中初始化狀態的方式。

還有一個處理提交的函數,其中,e.preventDefault來阻止頁面刷新並列印出表單值。

updateField函數更有意思。它使用setValues傳遞一個對象,為了確保現有的狀態不被覆蓋,這裡使用了展開運算(...form)。

代碼部署後可能存在的BUG沒法實時知道,事後為瞭解決這些BUG,花了大量的時間進行log 調試,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug

原文:https://daveceddia.com/usestate-hook-examples/

關於Fundebug

Fundebug專註於JavaScript、微信小程式、微信小游戲、支付寶小程式、React Native、Node.js和Java線上應用實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了20億+錯誤事件,付費客戶有陽光保險、核桃編程、荔枝FM、掌門1對1、微脈、青團社等眾多品牌企業。歡迎大家免費試用


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 瀏覽器 1. shell: 外殼 2. core: 內核(JS執行引擎,渲染引擎) IE: Trident Firefox: Gecko Chrome: Webkit / Blink safari: Webkit opera: Presto / Blink ...
  • 1、什麼是預解析? 在當前作用域下,JS 運行之前,會把帶有 var 和 function 關鍵字的事先聲明,併在記憶體中安排好。(這個過程也可以理解為變數提升)然後再從上到下執行 JS 語句(預解析只會發生在通過 var 定義的變數和 function 上) 2、var 聲明的變數 使用 var 聲 ...
  • JavaScript 誕生於1995年,它的出現主要是用於處理網頁中的 前端驗證。 • 所謂的前端驗證,就是指檢查用戶輸入的內容是否符合一定的 規則。 • 比如:用戶名的長度,密碼的長度,郵箱的格式等。 JavaScript是由網景公司發明,起初命名為LiveScript,後來由 於SUN公司的介入 ...
  • css作用:控制網頁的樣式 css語法: 選擇符{ 屬性1:屬性值; 屬性2:屬性值; 屬性3:屬性值1 屬性值2 屬性值3; } css實例: div{ width:300px; height:400px; background:red; } css語法解釋: 1、選擇符:對標簽進行獲取 2、所有 ...
  • 預解析指的就是,在js文件或者script裡面的代碼在正式開始執行之前,進行的一些解析工作。這個工作很簡單,就是在全局中尋找var關鍵字聲明的變數和通過function關鍵字聲明的函數。 1.尋找 var function 參數 等關鍵字,根據var a提前設置為 a=未定義(undefined)  ...
  • 今天詳細講解JavaScript中的常用事件類型和功能。 一 滑鼠事件 1, click:點擊事件 等同於mousedown+mouseup,不管這兩個事件間隔多久,都會觸發一次click事件。 2, mousedown:滑鼠按下事件 3, mouseup:滑鼠彈起事件 4, mouseover/m ...
  • 問題:在H5中,我們有這樣的需求:例如有列表的時候,滾動到底部時,需要載入更多。 解決方案:可以採用window的滾動事件進行處理 分析:如果滾動是針對整個屏幕而言的(不針對於某個界面小塊),那麼這個應該是是成立的:屏幕的高度+最大滾動的距離 = 內容的高度 代碼實現: 代碼的相關說明:很多時候,列 ...
  • 百度防抖與節流,一直沒搞懂防抖與節流的區別,然後google了一下,(google大法好 _(:з」∠)_)個人理解了一下 1,比較正式的解釋他們的區別: 防抖:就是指觸發事件後在 n 秒內函數只能執行一次,如果在 n 秒內又觸發了事件,則會重新計算函數執行時間,防抖註重結果 節流::是讓一個函數無 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...