<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        React 使用Hooks簡化受控組件的狀態綁定

        來源:懂視網 責編:小采 時間:2020-11-27 21:59:58
        文檔

        React 使用Hooks簡化受控組件的狀態綁定

        React 使用Hooks簡化受控組件的狀態綁定:開始之前 閱讀本文需要對以下幾項有一定了解 ECMAScript 6 文章中大量用到了 ES6 語法,比如解構賦值和函數參數默認值、剩余參數、展開語法、箭頭函數等。 Hooks React 在 16.8 版本中推出了 Hooks,它允許你在函數組件中使用類組件的一些特性。
        推薦度:
        導讀React 使用Hooks簡化受控組件的狀態綁定:開始之前 閱讀本文需要對以下幾項有一定了解 ECMAScript 6 文章中大量用到了 ES6 語法,比如解構賦值和函數參數默認值、剩余參數、展開語法、箭頭函數等。 Hooks React 在 16.8 版本中推出了 Hooks,它允許你在函數組件中使用類組件的一些特性。

        開始之前

        閱讀本文需要對以下幾項有一定了解

        ECMAScript 6

        文章中大量用到了 ES6 語法,比如解構賦值和函數參數默認值、剩余參數、展開語法、箭頭函數等。

        Hooks

        React 在 16.8 版本中推出了 Hooks,它允許你在“函數組件”中使用“類組件”的一些特性。

        React 本身提供了一些 Hooks,比如 useState、useReducer 等。通過在一個以“use”作為命名起始的函數中調用這些 Hooks,就得到了一個 custom Hook(自定義 Hook)。

        Custom Hooks 允許我們把任何邏輯封裝到其中,以便于復用足夠小的組件邏輯。

        Controlled Components

        當我們把像 <input> <textarea> 和 <select> 這樣的 HTML 元素本身的狀態交給 React state 去管理,我們就得到了一個“受控組件”。

        styled-components

        一個與 React 契合良好的 CSS in JS 庫。它允許你使用 JS 編寫樣式,并編譯成純 CSS 文件。
        下面代碼中所有的樣式都是使用它編寫的。如果對代碼中樣式的實現不是很感興趣的話, 這個可以跳過。

        代碼實現

        Input 組件

        首先我們需要實現一個 Input 組件,我們將在該組件的基礎上進行輸入、校驗并提示。

        Input.js

        import React from 'react';
        import PropTypes from 'prop-types';
        import styled from 'styled-components';
        
        const Wrap = styled.div({
         display: 'flex',
         flexDirection: 'column',
        
         label: { display: 'flex', alignItems: 'center' },
        
         input: {
         marginLeft: 8,
         },
        
         p: {
         color: 'red',
         },
        });
        
        function Input({ label, type, helperText, error, ...otherProps }) {
         return (
         <Wrap>
         <label>
         {label}:
         <input {...otherProps} type={type} />
         </label>
         {error && <p>{helperText}</p>}
         </Wrap>
         );
        }
        
        Input.propTypes = {
         label: PropTypes.string,
         type: PropTypes.string,
         helperText: PropTypes.string,
         error: PropTypes.bool,
        };
        
        export default Input;
        
        

        該組件主要接收以下幾個 props:

      1. label label 標簽的文本
      2. type 賦值給原生 input 標簽的 type 屬性
      3. error 數據類型為 Boolean,如果為 true 則表示當前表單域有錯誤,即驗證不通過
      4. helperText 當前表單域驗證不通過時,顯示在表單域下方的提示文字
      5. otherProps props 中除了上述四個以外的其他屬性,全部賦值給原生 input 標簽
      6. Custom Hook

        有了 UI 組件之后,就可以開始實現我們的自定義 Hook 了。

        useInput.js

        import { useState } from 'react';
        
        export default function useInput({
         initValue = '',
         helperText = '',
         validator = () => true,
         validateTriggers = ['onChange'],
        } = {}) {
         // 保存用戶輸入的值,使用 initValue 作為初始值
         const [value, setValue] = useState(initValue);
         // Boolean 類型,表示當前表單項的驗證狀態
         const [error, setError] = useState(false);
        
         function onChange(e) {
         const { value } = e.target;
        
         setValue(value);
        
         // 根據 validateTriggers 的選項,決定是否要在 onChange 里進行校驗
         if (validateTriggers.includes('onChange')) {
         setError(!validator(value));
         }
         }
        
         /**
         * 根據 validateTriggers 生成相應的事件處理器
         */
         function createEventHandlers() {
         const eventHandlers = {};
        
         validateTriggers.forEach(item => {
         // 生成相應的事件處理器,并在其中做輸入校驗。
         eventHandlers[item] = e => {
         const { value } = e.target;
         setError(!validator(value));
         };
         });
        
         return eventHandlers;
         }
        
         const eventHandlers = createEventHandlers();
        
         return {
         value,
         helperText,
         error,
         ...eventHandlers,
         onChange,
         };
        }
        
        

        useInput 接收一個 options 對象作為參數,考慮到擴展性,使用一個配置對象作為參數比較好。

        options 對象擁有以下幾個屬性:

      7. initValue 輸入框的初始值
      8. helperText 當表單驗證不通過時顯示的字符串
      9. validator 用于進行表單驗證的函數,接收 value 作為參數,并返回一個 Boolean 值,表示表單驗證是否通過
      10. validateTriggers 字符串數組,表明在哪個或哪幾個事件中調用 validator 進行輸入校驗。
      11. 在函數體中,我們調用兩次 useState 來初始化 value 和 error 的值,分別保存用戶輸入的值和當前表單域的校驗結果。
        然后,聲明一個 onChange 方法用來綁定 input 元素的 change 事件,在該方法中,我們把用戶輸入的值賦值給 value,同時根據 validateTriggers 的值,決定是否要在該方法中進行輸入校驗。該方法隨后會被返回出去,再作為 props 傳遞給相應的組件,完成受控組件的狀態綁定。

        我們還需要聲明一個 createEventHandlers 方法,該方法通過遍歷 validateTriggers,生成相應的事件處理器,并在這些事件處理器中進行輸入校驗。

        最后我們調用 createEventHandlers 方法,并把生成的 eventHandlers(事件處理器) 通過擴展運算符,插入到最終返回的對象中。

        注意:這里我們需要把 onChange 放在最后,以免帶有狀態綁定的 onChange 方法被 eventHandlers 中的 onChange 覆蓋掉。

        具體使用

        現在讓我們來看看實際該如何使用:

        import React from 'react';
        import Input from './Input';
        import useInput from './useInput';
        
        // 用于驗證郵箱的正則表達式
        const EMAIL_REG = /\S+@\S+\.\S+/;
        
        export default function Form() {
         const email = useInput({
         initValue: '',
         helperText: '請輸入有效的郵箱!',
         validator: value => EMAIL_REG.test(value),
         validateTriggers: ['onBlur'],
         });
        
         const password = useInput({
         initValue: '',
         helperText: '密碼長度需要在 6-20 之間!',
         validator: value => value.length >= 6 && value.length <= 20,
         validateTriggers: ['onChange', 'onBlur'],
         });
        
         /**
         * 判斷是否禁用按鈕
         */
         function isButtonDisabled() {
         // 當郵箱或密碼未填寫時,或者郵箱或密碼輸入校驗未通過時,禁用按鈕
         return !email.value || !password.value || email.error || password.error;
         }
        
         /**
         * 處理表單提交
         */
         function handleButtonClick() {
         console.log('郵箱:', email.value);
         console.log('密碼:', password.value);
         }
        
         return (
         <div>
         <Input {...email} label="郵箱" type="email" />
         <Input {...password} label="密碼" type="password" />
        
         <button disabled={isButtonDisabled()} onClick={handleButtonClick}>
         登錄
         </button>
         </div>
         );
        }
        
        

        這里調用了兩次 useInput,初始化 email 和 password 表單域數據。

        然后使用擴展運算符,把值全部賦給 Input 組件。只用了幾行代碼就完成了定義初始值和受控組件的綁定,是不是很方便?

        當我們輸入郵箱的時候,并不會出現校驗提示,但是一旦從郵箱輸入框失去焦點以后,輸入的值就會被校驗,并根據校驗結果顯示相應的提示。而密碼輸入框,則會在輸入的過程中和失焦后都進行校驗。

        總結

        上面這個例子已經可以處理基本的表單驗證,至于格式化用戶輸入的數據以及自定義收集表單域的值的時機等其他需求,我就不再演示了,大家可以自行設計。這也是 Hooks 的特殊之處,它讓我們可以更容易的復用邏輯代碼,可以根據需要自行編寫 custom Hooks。

        文章中關于 useInput 的 API 設計只是眾多方案中的一種,只是為大家提供一些參考。你也可以把整個表單的狀態封裝到一個 useForm 方法中,統一管理所有表單域的狀態。

        希望本文能為大家帶來一些關于如何使用 Hooks 的靈感,即使從來沒有使用過 Hooks,也強烈建議大家嘗試一下。我已經在項目中大量使用 Hooks 了,并且它也為我帶來了很好的效果。

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        React 使用Hooks簡化受控組件的狀態綁定

        React 使用Hooks簡化受控組件的狀態綁定:開始之前 閱讀本文需要對以下幾項有一定了解 ECMAScript 6 文章中大量用到了 ES6 語法,比如解構賦值和函數參數默認值、剩余參數、展開語法、箭頭函數等。 Hooks React 在 16.8 版本中推出了 Hooks,它允許你在函數組件中使用類組件的一些特性。
        推薦度:
        標簽: 的狀態 React hooks
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲色偷偷综合亚洲av78| 18gay台湾男同亚洲男同| 亚洲精品无播放器在线播放| 成人免费大片免费观看网站| 亚洲黄色中文字幕| 无码区日韩特区永久免费系列| 亚洲美女精品视频| 免费国产成人高清在线观看网站 | 亚洲午夜无码久久久久| 国产免费牲交视频免费播放| 久久亚洲国产精品五月天婷| 一个人看的www视频免费在线观看| 国内精品久久久久久久亚洲| 男人天堂免费视频| 亚洲黄色网址大全| 成年性羞羞视频免费观看无限| 亚洲成熟丰满熟妇高潮XXXXX | 亚洲免费人成在线视频观看 | 亚洲精品无码久久久久APP| 国产美女精品视频免费观看| 亚洲精品乱码久久久久蜜桃| 亚洲Av无码国产情品久久| 中文字幕免费在线播放| 亚洲成人动漫在线观看| 国产小视频在线免费| 特a级免费高清黄色片| 亚洲男人都懂得羞羞网站| 无码日韩人妻av一区免费| 成人精品国产亚洲欧洲| 国产亚洲综合网曝门系列| a毛片基地免费全部视频| 野花视频在线官网免费1| 亚洲va久久久噜噜噜久久| 性生交片免费无码看人| 国产vA免费精品高清在线观看| 亚洲国产成人一区二区三区| 在线观看av永久免费| 国产成人高清精品免费观看| 91情国产l精品国产亚洲区| 国产在线不卡免费播放| 污污网站免费观看|