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

基于React封裝一個(gè)驗(yàn)證碼輸入控件

 更新時(shí)間:2024年03月27日 10:27:28   作者:墨淵君  
郵箱、手機(jī)驗(yàn)證碼輸入是許多在線服務(wù)和網(wǎng)站常見(jiàn)的安全驗(yàn)證方式之一,本文主要來(lái)和大家討論一下如何使用React封裝一個(gè)驗(yàn)證碼輸入控件,感興趣的可以了解下

引言

郵箱、手機(jī)驗(yàn)證碼輸入是許多在線服務(wù)和網(wǎng)站常見(jiàn)的安全驗(yàn)證方式之一。這種方式通常用于確保用戶在進(jìn)行敏感操作(例如注冊(cè)、修改密碼、重置密碼等)時(shí)的身份驗(yàn)證。

最近在做項(xiàng)目剛好有驗(yàn)證碼相關(guān)的需求, 本著不重復(fù)造輪子的原則, 一頓 Google 試圖找到一個(gè)現(xiàn)成的組件, 奈何找了一圈都沒(méi)找到滿意的, 要么就是交互感覺(jué)不太合理、要么就是基本停止維護(hù)了的!!

最后沒(méi)辦法就自己造一個(gè)了, 這里主要參考了 react-auth-code-input, 而本文則是整個(gè)思路開(kāi)發(fā)流程的記錄!!

DEMO 演示可查閱: blog/auth-codes

本文完整源碼可查閱: coding/blog/AuthCodes

一、需求描述

開(kāi)始前我們先梳理下一般驗(yàn)證碼輸入控件的常規(guī)需求有哪些:

  • 假設(shè)我們驗(yàn)證碼有 6 位, 則我們需要有 6 個(gè)輸入框, 每個(gè)輸入框只允許輸入一位數(shù)字(這里假設(shè)驗(yàn)證碼都是數(shù)字組成)
  • 在輸入驗(yàn)證碼過(guò)程中, 可連續(xù)進(jìn)行輸入、刪除等操作
  • 支持黏貼復(fù)制的內(nèi)容
  • ...

二、布局

在開(kāi)始前我們先來(lái)完成基本的布局, 如下代碼所示:

  • 聲明狀態(tài) codes 用于存儲(chǔ)每個(gè)驗(yàn)證碼, 也就是每個(gè)輸入框的值, 這里我將 codes 設(shè)置為一個(gè)數(shù)組, 方便后面修改每個(gè)位置的驗(yàn)證碼
  • 假設(shè)我們驗(yàn)證碼長(zhǎng)度為 6 位, 所以這里我為 codes 默認(rèn)值了一個(gè)長(zhǎng)度為 6 的數(shù)組, 數(shù)組每個(gè)初始值為空字符串
  • 然后我們通過(guò) codes.map 渲染出所有輸入框
  • 最后我們還聲明了 inputsRef 來(lái)存儲(chǔ)所有輸入框的 DOM 節(jié)點(diǎn), 我們后面需要通過(guò)它來(lái)調(diào)用原生 DOMAPI
import React, { useState, useRef } from 'react';
import scss from './com.module.scss';

export default () => {
  const [codes, setCodes] = useState(Array.from({ length: 6 }, () => ''));
  const inputsRef = useRef([]);

  return (
    <div>
      {codes.map((value, index) => (
        <input
          type="text"
          key={index}
          value={value}
          maxLength={1}
          className={scss.input}
          ref={(ele) => (inputsRef.current[index] = ele)}
        />
      ))}
    </div>
  );
};

這里我們對(duì)輸入框設(shè)置了一些基本的樣式

.input {
  width: 40px;
  margin: 10px;

  font-size: 18px;
  line-height: 40px;
  text-align: center;

  border-radius: 4px;
  border: 1px solid #d9d9d9;
}

到此頁(yè)面的基本效果如下:

三、動(dòng)態(tài)綁定(處理 onChange 事件)

上文只是完成了基本的布局, 并且輸入框 value 和狀態(tài) codes 內(nèi)的值綁定在了一起, 這里輸入框輸入值會(huì)發(fā)現(xiàn)并沒(méi)有生效, 那是因?yàn)闋顟B(tài) codes 沒(méi)有被修改!

下面我們?yōu)檩斎肟蛟O(shè)置 onChange 事件, 在輸入框輸入值時(shí)動(dòng)態(tài)的修改狀態(tài) codes 中對(duì)應(yīng)位置的值!!

下面是 onChange 事件的處理函數(shù):

  • 兩個(gè)參數(shù), indexevent, 正如命名所示, index 對(duì)應(yīng)輸入框索位置, event 則是輸入對(duì)應(yīng)的 change 事件對(duì)象, 通過(guò)它來(lái)獲取輸入值
  • 特別說(shuō)明, 本文驗(yàn)證碼都是數(shù)字, 所以在函數(shù)內(nèi)部還需要針對(duì)輸入內(nèi)容進(jìn)行校驗(yàn), 只允許輸入數(shù)字 0~9
  • 函數(shù)內(nèi)還有一個(gè)特殊處理邏輯, 就是當(dāng)我們輸入有效值后, 需要將鼠標(biāo)光標(biāo)聚焦到下一個(gè)輸入框, 如此用戶就可以連續(xù)進(jìn)行輸入了, 至于實(shí)現(xiàn)方法很簡(jiǎn)單, 這里直接調(diào)用 inputsRef 中對(duì)應(yīng)輸入框 DOM 節(jié)點(diǎn)的 focus 方法即可
  • 最后我們調(diào)用, setCodes 修改狀態(tài) codes, 這樣輸入框的值才能動(dòng)態(tài)的修改
const handleChange = useCallback((index, event) => {
  const currentValue = event.target.value.match(/[0-9]{1}/)
    ? event.target.value
    : '';

  // 如果輸入有效值, 則自動(dòng)聚焦到下一個(gè)輸入框
  if (currentValue) {
    inputsRef.current[index + 1]?.focus();
  }

  setCodes((pre) => {
    const newData = [...pre];
    newData[index] = currentValue;
    return newData;
  });
}, []);

最為為每個(gè)輸入框綁定 onChange 事件, 主要這里使用了 bind 來(lái)綁定 index:

<div>
  {codes.map((value, index) => (
    <input
      ...
+     onChange={handleChange.bind(null, index)}
      ref={(ele) => (inputsRef.current[index] = ele)}
    />
  ))}
</div>

最后效果如下: 輸入驗(yàn)證碼, 光標(biāo)自動(dòng)跳轉(zhuǎn)到下一個(gè)輸入框

四、刪除處理

上文我們完成驗(yàn)證碼的輸入, 但是在輸入過(guò)程中, 難免會(huì)輸入錯(cuò)誤的數(shù)字, 所以就需要實(shí)現(xiàn)刪除驗(yàn)證碼的能力, 需求如下:

  • 當(dāng)我們按下 刪除鍵
  • 如果當(dāng)前輸入框有值, 則刪除當(dāng)前輸入框中的內(nèi)容
  • 如果當(dāng)前輸入框沒(méi)有值, 則刪除上一個(gè)輸入框內(nèi)容, 并且聚焦到上一個(gè)輸入框

需求其實(shí)已經(jīng)很明確了, 我只需要通過(guò) onKeyDown 來(lái)監(jiān)聽(tīng)鍵盤(pán)按下事件, 從而判斷用戶是否按下 刪除鍵, 如果按下 刪除鍵 則按照需求邏輯進(jìn)行編碼即可, 具體代碼如下:

  • 函數(shù)接收兩個(gè)參數(shù) indexevent, index 表示當(dāng)前光標(biāo)所在的輸入框索引位置, event 則是事件對(duì)象
  • 通過(guò) event.key 的值來(lái)確定是否按下 刪除鍵(Backspace), 如果不是, 則不進(jìn)行任何處理
  • 剩下就按需求來(lái), 如果當(dāng)前輸入框有值則清除當(dāng)前輸入框內(nèi)容
  • 如果當(dāng)前輸入框沒(méi)值, 則清除上一個(gè)輸入框內(nèi)容, 并且將光標(biāo)移到上一個(gè)輸入框中, 這里還需要考慮下邊界情況, 如果當(dāng)前輸入框已經(jīng)是第一個(gè)了, 就無(wú)需進(jìn)行任何處理
const handleDelete = useCallback((index, event) => {
  const { key } = event;

  // 是否按下刪除鍵, 否提前結(jié)束
  if (key !== 'Backspace') {
    return;
  }

  // 1. 如果當(dāng)前輸入框有值, 則刪除當(dāng)前輸入框內(nèi)容
  if (codes[index]) {
    setCodes((pre) => {
      const newData = [...pre];
      newData[index] = '';
      return newData;
    });
  } else if (index > 0) {
    // 2. 如果當(dāng)前輸入框沒(méi)有值(考慮下邊界的情況 index === 0): 則刪除上一個(gè)輸入框內(nèi)容, 并且光標(biāo)聚焦到上一個(gè)輸入框
    setCodes((pre) => {
      const newData = [...pre];
      newData[index - 1] = '';
      return newData;
    });
    inputsRef.current[index - 1].focus();
  }
}, [codes]);

最后為每個(gè)輸入框綁定 onKeyDown 事件, 主要這里使用了 bind 來(lái)綁定 index:

<div>
  {codes.map((value, index) => (
    <input
      ...
+     onKeyDown={handleDelete.bind(null, index)}
      onChange={handleChange.bind(null, index)}
      ref={(ele) => (inputsRef.current[index] = ele)}
    />
  ))}
</div>

最后效果如下: 輸入驗(yàn)證碼后, 按下刪除鍵, 能夠連續(xù)刪除驗(yàn)證碼內(nèi)容

五、粘貼處理

在大部分情況下, 我們都是直接復(fù)制驗(yàn)證碼然后直接黏貼使用, 所以我們接下來(lái)來(lái)實(shí)現(xiàn)的功能就是:

  • 允許在任意輸入框黏貼數(shù)據(jù)
  • 自動(dòng)將剪切板的數(shù)字回填到輸入框中
  • 這里不做過(guò)多的處理, 不管光標(biāo)在哪個(gè)位置, 都從第一個(gè)輸入框開(kāi)始填充數(shù)字
  • 注意的是, 這里光標(biāo)還需要自動(dòng)聚焦到最后一個(gè)輸入框內(nèi)容為空的位置

具體實(shí)現(xiàn)代碼如下:

  • 通過(guò) event.clipboardData.getData 獲取到剪切板內(nèi)容
  • 過(guò)濾掉剪切板中非數(shù)值部分內(nèi)容
  • 生成新?tīng)顟B(tài) codes: 先創(chuàng)建了一長(zhǎng)度為 6 的數(shù)組, 并使用剪切板的數(shù)字就行填充, 不夠的用空字符進(jìn)行填充, 最后使用 setCodes 來(lái)修改狀態(tài)值
  • 光標(biāo)位置修改, 根據(jù)剪切板數(shù)字長(zhǎng)度來(lái)進(jìn)行計(jì)算
const handlePaste = useCallback((event) => {
  const pastedValue = event.clipboardData.getData('Text'); // 讀取剪切板數(shù)據(jù)
  const pastNum = pastedValue.replace(/[^0-9]/g, ''); // 去除數(shù)據(jù)中非數(shù)字部分, 只保留數(shù)字

  // 重新生成 codes: 6 位, 每一位取剪切板對(duì)應(yīng)位置的數(shù)字, 沒(méi)有則置空
  const newData = Array.from(
    { length: 6 },
    (_, index) => pastNum.charAt(index) || '',
  );

  setCodes(newData); // 修改狀態(tài) codes

  // 光標(biāo)要聚焦的輸入框的索引, 這里取 pastNum.length 和 5 的最小值即可, 當(dāng)索引為 5 就表示最后一個(gè)輸入框了
  const focusIndex = Math.min(pastNum.length, 5);
  inputsRef.current[focusIndex]?.focus();
}, []);

最后為每個(gè)輸入框綁定 onPaste(黏貼) 事件

<input
  ...
  onPaste={handlePaste}
/>

最后效果如下: 光標(biāo)聚焦在任意輸入框, 進(jìn)行黏貼后, 即可自動(dòng)用剪切板內(nèi)的數(shù)字來(lái)填充輸入框

六、第一階段完成

到此整體功能已經(jīng)差不多了, 下面是目前為止完整的代碼(刪除了 CSS 部分)

import React, { useState, useRef, useCallback } from 'react';

export default () => {
  const [codes, setCodes] = useState(Array.from({ length: 6 }, () => ''));
  const inputsRef = useRef([]);

  const handleChange = useCallback((index, event) => {
    const currentValue = event.target.value.match(/[0-9]{1}/)
      ? event.target.value
      : '';

    // 如果輸入有效值, 則自動(dòng)聚焦到下一個(gè)輸入框
    if (currentValue) {
      inputsRef.current[index + 1]?.focus();
    }

    setCodes((pre) => {
      const newData = [...pre];
      newData[index] = currentValue;
      return newData;
    });
  }, []);

  const handleDelete = useCallback((index, event) => {
    const { key } = event;

    // 是否按下刪除鍵, 否提前結(jié)束
    if (key !== 'Backspace') {
      return;
    }

    // 1. 如果當(dāng)前輸入框有值, 則刪除當(dāng)前輸入框內(nèi)容
    if (codes[index]) {
      setCodes((pre) => {
        const newData = [...pre];
        newData[index] = '';
        return newData;
      });
    } else if (index > 0) {
      // 2. 如果當(dāng)前輸入框沒(méi)有值(考慮下邊界的情況 index === 0): 則刪除上一個(gè)輸入框內(nèi)容, 并且光標(biāo)聚焦到上一個(gè)輸入框
      setCodes((pre) => {
        const newData = [...pre];
        newData[index - 1] = '';
        return newData;
      });
      inputsRef.current[index - 1].focus();
    }
  }, [codes]);

  const handlePaste = useCallback((event) => {
    const pastedValue = event.clipboardData.getData('Text'); // 讀取剪切板數(shù)據(jù)
    const pastNum = pastedValue.replace(/[^0-9]/g, ''); // 去除數(shù)據(jù)中非數(shù)字部分, 只保留數(shù)字

    // 重新生成 codes: 6 位, 每一位取剪切板對(duì)應(yīng)位置的數(shù)字, 沒(méi)有則置空
    const newData = Array.from(
      { length: 6 },
      (_, index) => pastNum.charAt(index) || '',
    );

    setCodes(newData); // 修改狀態(tài) codes

    // 光標(biāo)要聚焦的輸入框的索引, 這里取 pastNum.length 和 5 的最小值即可, 當(dāng)索引為 5 就表示最后一個(gè)輸入框了
    const focusIndex = Math.min(pastNum.length, 5);
    inputsRef.current[focusIndex]?.focus();
  }, []);

  return (
    <div>
      {codes.map((value, index) => (
        <input
          type="text"
          key={index}
          value={value}
          maxLength={1}
          onPaste={handlePaste}
          onKeyDown={handleDelete.bind(null, index)}
          onChange={handleChange.bind(null, index)}
          ref={(ele) => (inputsRef.current[index] = ele)}
        />
      ))}
    </div>
  );
};

基本功能有了, 下面我們對(duì)組件進(jìn)行簡(jiǎn)單的封裝、優(yōu)化....

七、暴露 onChange 事件

這里我們希望父組件可以通過(guò) onValueChange 來(lái)監(jiān)聽(tīng)到內(nèi)部狀態(tài) codes 的變更, 做法就很簡(jiǎn)單了:

  • 抽離一個(gè)通過(guò)方法 resetCodes, 修改狀態(tài)的地方全部使用 resetCodes 方法
  • resetCodes 方法內(nèi)部則是調(diào)用 setCodes 方法修改 codes 同時(shí)調(diào)用父組件傳進(jìn)來(lái)的 onValueChange 方法
  • resetCodes 支持傳一個(gè)數(shù)組進(jìn)來(lái), 也可以是一個(gè) index 一個(gè) value; 這么做的原因主要是為了支持不同場(chǎng)景下修改狀態(tài) codes 的需求
// 修改狀態(tài) codes
const resetCodes = useCallback((index, value) => {
  setCodes((pre) => {
    let newData = [...pre];

    if (Array.isArray(index)) {
      newData = index;
    }

    if (typeof index === 'number') {
      newData[index] = value;
    }

    onValueChange?.(newData.join(''));

    return newData;
  });
}, [onValueChange]);

最后還需要將代碼里調(diào)用 setCodes 的地方改為 resetCodes, 這里就不做演示了; 修改完成之后, 我們就可以通過(guò) onValueChange 監(jiān)聽(tīng)到組件內(nèi)部 codes 的變更了

<AuthCode onValueChange={(codes) => console.log(codes)} />

最后效果如下:

八、暴露 onComplete 事件

這里我們還希望在輸入完所有驗(yàn)證碼后, 能夠被組件外部監(jiān)聽(tīng)到, 這樣就可以直接拿到完整的驗(yàn)證碼向后端服務(wù)發(fā)起校驗(yàn)....

其實(shí)有了上面的基礎(chǔ), 我們可以直接在 resetCodes 中進(jìn)行處理: 在修改狀態(tài) codes 前判斷下所有驗(yàn)證碼是否都已經(jīng)輸入, 如果已全部輸入則調(diào)用父組件的 onComplete 事件

// 修改狀態(tài) codes
const resetCodes = useCallback((index, value) => {
  setCodes((pre) => {
    let newData = [...pre];

    if (Array.isArray(index)) {
      newData = index;
    }

    if (typeof index === 'number') {
      newData[index] = value;
    }

+   // 處理 onComplete
+   if (newData.every(Boolean) && onComplete) {
+     onComplete(newData.join(''));
+   }

    onValueChange?.(newData.join(''));

    return newData;
  });
+ }, [onValueChange, onComplete]);

接下來(lái)我們就可以在驗(yàn)證碼全部輸入后, 通過(guò) onComplete 監(jiān)聽(tīng)到

<AuthCode onComplete={(codes) => console.log(codes)} />

最后效果如下:

九、自動(dòng)聚焦

這個(gè)需求就很簡(jiǎn)單咯, 就是希望組件在初始化時(shí)可以將鼠標(biāo)光標(biāo)自動(dòng)聚焦到第一個(gè)輸入框, 這樣用戶就可以直接進(jìn)行輸入, 完成驗(yàn)證碼的校驗(yàn)!!!

實(shí)現(xiàn)方法就更簡(jiǎn)單, 直接在 useEffect 中調(diào)用第一個(gè)輸入框的 DOM 節(jié)點(diǎn)的原生 focus 方法即可

useEffect(() => {
  inputsRef.current[0].focus();
}, []);

十、聚焦時(shí)選中輸入框內(nèi)容

下面我們希望能夠在輸入框聚焦情況下, 能夠自動(dòng)選中輸入框的內(nèi)容, 這樣的話就可以直接輸入內(nèi)容, 而不是先刪除再輸入內(nèi)容!!

實(shí)現(xiàn)方法很簡(jiǎn)單:

  • 通過(guò) onFocus 事件來(lái)實(shí)現(xiàn), 監(jiān)聽(tīng) Focus(獲取焦點(diǎn)) 事件
  • 然后在事件處理函數(shù)內(nèi)調(diào)用事件 select 方法來(lái)選中輸入框的內(nèi)容
const handleOnFocus = useCallback((e) => {
  e.target.select();
}, []);

最后效果如下:

十一、暴露外面接口

最后我們希望父組件可以通過(guò) ref 來(lái)獲取到一些組件內(nèi)部預(yù)設(shè)好的方法, 比如自動(dòng)獲取焦點(diǎn)、清空所有輸入框內(nèi)容等等

如下代碼使用 forwardRef 配合 useImperativeHandle 完成 ref 的綁定

export default forwardRef((props, ref) => {
  // ...
  useImperativeHandle(ref, () => ({
    // 獲取焦點(diǎn)
    focus: (index = 0) => {
      if (inputsRef.current) {
        inputsRef.current[index].focus();
      }
    },
    // 清空內(nèi)容
    clear: () => {
      resetCodes(codes.map(() => ''));
    },
  }));
  // ...
}

調(diào)用方法如下所示:

export default () => {
  const ref = useRef();
  return (
    <>
      <Com ref={ref} />
      <Button onClick={() => ref.current?.clear()}>
        清空
      </Button>
    </>
  );
};

最后效果如下:

十二、后續(xù)

到此基本差不多了, 剩下更多的可能是組件的封裝上的事情, 比如:

  • 允許設(shè)置默認(rèn)值
  • 支持雙向綁定
  • 支持設(shè)置驗(yàn)證碼長(zhǎng)度
  • 支持設(shè)置驗(yàn)證碼規(guī)則(純數(shù)字、純字母、字母數(shù)字混合)
  • 支持設(shè)置 input 參數(shù)(比如 placeholder 等等)
  • ...

以上就是基于React封裝一個(gè)驗(yàn)證碼輸入控件的詳細(xì)內(nèi)容,更多關(guān)于React封裝驗(yàn)證碼輸入控件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • react中常見(jiàn)hook的使用方式

    react中常見(jiàn)hook的使用方式

    這篇文章主要介紹了react中常見(jiàn)hook的使用方式與區(qū)別,幫助大家更好的理解和學(xué)習(xí)使用react,感興趣的朋友可以了解下
    2021-04-04
  • React+Koa實(shí)現(xiàn)文件上傳的示例

    React+Koa實(shí)現(xiàn)文件上傳的示例

    這篇文章主要介紹了React+Koa實(shí)現(xiàn)文件上傳的示例,幫助大家更好的理解和學(xué)習(xí)使用React,感興趣的朋友可以了解下
    2021-04-04
  • 編寫(xiě)簡(jiǎn)潔React組件的小技巧

    編寫(xiě)簡(jiǎn)潔React組件的小技巧

    這篇文章主要介紹了編寫(xiě)簡(jiǎn)潔React組件的小技巧,幫助大家更好的理解和學(xué)習(xí)使用React,感興趣的朋友可以了解下
    2021-04-04
  • React處理表單輸入的幾種主要方法

    React處理表單輸入的幾種主要方法

    在現(xiàn)代前端開(kāi)發(fā)中,表單是用戶與應(yīng)用程序進(jìn)行交互的最主要方式之一,React,作為一款強(qiáng)大的視圖庫(kù),提供了多種靈活的方式來(lái)處理表單數(shù)據(jù),本文將深入探討 React 中處理表單輸入的幾種主要方法,需要的朋友可以參考下
    2025-08-08
  • React中 Zustand狀態(tài)管理庫(kù)的使用詳解

    React中 Zustand狀態(tài)管理庫(kù)的使用詳解

    Zustand?是一個(gè)非常輕量、簡(jiǎn)潔的狀態(tài)管理庫(kù),旨在為 React 提供簡(jiǎn)便且高效的狀態(tài)管理,相比于 Redux 或 Context API,Zustand 具有更簡(jiǎn)潔、靈活和易于理解的優(yōu)點(diǎn),感興趣的朋友一起看看吧
    2024-12-12
  • react-redux中connect的裝飾器用法@connect詳解

    react-redux中connect的裝飾器用法@connect詳解

    這篇文章主要介紹了react-redux中connect的裝飾器用法@connect詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • 簡(jiǎn)談創(chuàng)建React Component的幾種方式

    簡(jiǎn)談創(chuàng)建React Component的幾種方式

    這篇文章主要介紹了創(chuàng)建React Component的幾種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下
    2019-06-06
  • 使用react-beautiful-dnd實(shí)現(xiàn)列表間拖拽踩坑

    使用react-beautiful-dnd實(shí)現(xiàn)列表間拖拽踩坑

    相比于react-dnd,react-beautiful-dnd更適用于列表之間拖拽的場(chǎng)景,本文主要介紹了使用react-beautiful-dnd實(shí)現(xiàn)列表間拖拽踩坑,感興趣的可以了解一下
    2021-05-05
  • react四種組件中DOM樣式設(shè)置方式詳解

    react四種組件中DOM樣式設(shè)置方式詳解

    這篇文章主要介紹了react之四種組件中DOM樣式設(shè)置方式,通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-10-10
  • 使用 Rails API 構(gòu)建一個(gè) React 應(yīng)用程序的詳細(xì)步驟

    使用 Rails API 構(gòu)建一個(gè) React 應(yīng)用程序的詳細(xì)步驟

    這篇文章主要介紹了使用 Rails API 構(gòu)建一個(gè) React 應(yīng)用程序的詳細(xì)步驟,主要包括后端:Rails API部分,前端:React部分及React組件的相關(guān)操作,具有內(nèi)容詳情跟隨小編一起看看吧
    2021-08-08

最新評(píng)論

从化市| 曲周县| 昭觉县| 怀远县| 宽城| 始兴县| 大新县| 沧源| 扎鲁特旗| 龙川县| 阿巴嘎旗| 鄂托克前旗| 辽阳市| 威远县| 武功县| 合水县| 柞水县| 凤山市| 凯里市| 罗山县| 安庆市| 两当县| 沭阳县| 德化县| 鸡泽县| 凤台县| 太湖县| 页游| 宜章县| 穆棱市| 柳江县| 县级市| 周口市| 五莲县| 黄浦区| 胶州市| 利川市| 来安县| 高青县| 黄石市| 舟曲县|