์‚ฌ์šฉ ์Šคํƒ ๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ: React, lodash

 

์–˜ ์ข€ ๊ท€์—ฝ๋„ค ์ฒธ์‹œ? ์ฒธ์„ธ์ด?

 
 

Debounce ์‚ฌ์šฉ ๋ชฉ์ : ๊ฒ€์ƒ‰์‹œ input์˜ onChange๋งˆ๋‹ค ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์„ debounce๋ฅผ ํ†ตํ•ด ๋ฐฉ์ง€

 

 

1. Input์˜ onChange๋ฅผ ํ†ตํ•œ api ํ˜ธ์ถœ

 
์•„๋ž˜ ํ•จ์ˆ˜๋ฅผ ์‚ดํŽด๋ณด์ž.
 

 
 
 
 
์ด ํ•จ์ˆ˜๋Š” input์— ํ…์ŠคํŠธ๋ฅผ ์ž…๋ ฅํ•  ๊ฒฝ์šฐ input์˜ onChange๋ฅผ ํ†ตํ•ด ํฌ์ผ“๋ชฌ์„ ์กฐํšŒํ•˜๋Š” api๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

input์˜ onChange๋Š” input์— ๊ฐ’์ด ์ž…๋ ฅ๋  ๋•Œ๋งˆ๋‹ค ํ˜ธ์ถœ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธ€์ž ์ˆ˜ ๋งŒํผ handleSearch ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์„ ์•„๋ž˜์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. (๊ฒ€์ƒ‰ ์„ฑ๋Šฅ ์ €ํ•˜)


 

 
 
์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด lodash์˜ debounce ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•ด ๋ณผ ๊ฒƒ์ด๋‹ค.

๐Ÿ’กLodash๋ž€? A modern JavaScript utility library delivering modularity, performance & extras. (๊ณต์‹ ๋ฌธ์„œ์—์„œ ์ •์˜ํ•˜๊ณ  ์žˆ๋Š” lodash์˜ ์˜๋ฏธ์ด๋‹ค; ๋ชจ๋“ˆ์„ฑ, ์„ฑ๋Šฅ๊ณผ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ๋“ฑ์„ ์ œ๊ณตํ•˜๋Š” ๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.)



2. Lodash์˜ debounce ์ ์šฉ

$ npm i -g npm //npm ์„ค์น˜ ์™„๋ฃŒ์‹œ ์ƒ๋žต
$ npm i --save lodash


์œ„ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด lodash๋ฅผ ์„ค์น˜ํ•œ๋‹ค.


 

Creates a debounced function that delays invoking func until after wait milliseconds have elapsed since the last time the debounced function was invoked.
 
 
 

import { debounce } from 'lodash';



ํ•„์š”ํ•œ ํ•จ์ˆ˜ debounce๋งŒ ๊ตฌ์กฐ๋ถ„ํ•ด๋กœ importํ•œ๋‹ค. (์ „์ฒด lodash๋ฅผ importํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ›จ์”ฌ ์ ๋‹ค)
 
 

   const getPokemon = debounce(async (value: string) => {
    await axios
      .get(`https://pokeapi.co/api/v2/pokemon/${value}`)
      .then((res) => {
        setPokemon(res);
      })
      .catch((err) => {
        return;
      });
  }, 300);

 
 
 
๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ธฐ์กด getPokemon ํ•จ์ˆ˜๋ฅผ debounce ํ•จ์ˆ˜๋กœ ๊ฐ์‹ธ์ค€๋’ค ์ง€์—ฐ์‹œ๊ฐ„์„ ์ˆซ์ž๋กœ ์ ์–ด์ค€๋‹ค. (์œ„ ์˜ˆ์‹œ์—์„œ๋Š” 0.3์ดˆ๋กœ ์„ค์ •) 
 
 
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด input์— ํƒ€์ดํ•‘์ด ๋˜๋”๋ผ๋„ ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ 0.3์ดˆ๋งˆ๋‹ค ํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
 
 

 3. State ๋ณ€๊ฒฝ๊ณผ debounce ๋™์‹œ ์ ์šฉ

๊ทธ๋ ‡๋‹ค๋ฉด ๋งŒ์•ฝ state ๋ณ€๊ฒฝ๊ณผ debouce๋ฅผ ํ•จ๊ป˜ ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ debounce๋Š” ํšจ๊ณผ์ ์œผ๋กœ ์ž‘๋™ํ• ๊นŒ?


์•„๋ž˜ handleSearch ํ•จ์ˆ˜๋Š” input์˜ onChange๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค(๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค) ์‹คํ–‰๋œ๋‹ค.

handleSearch๋‚ด์—์„œ setText๋ฅผ ํ†ตํ•ด ๋ณ€ํ•˜๋Š” input๊ฐ’์„ ๋™์‹œ์— ์ €์žฅํ•˜๊ณ , debounce๋ฅผ ํ†ตํ•ด api๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ํ•จ์ˆ˜๊ฐ€ ๋งŒ๋“ค์–ด์ง„๋‹ค.
 

const getPokemon = debounce(async (value: string) => {
    await axios
      .get(`https://pokeapi.co/api/v2/pokemon/${value}`)
      .then((res) => {
        setPokemon(res);
      })
      .catch((err) => {
        return;
      });
  }, 300);

const handleSearch = (e) => {
  setText(e.target.value);
  getPokemon(e.target.value);
}



์œ„ ํ•จ์ˆ˜์—์„œ ๋ฌธ์ œ์ ์€ ์šฐ๋ฆฌ์˜ ์˜ˆ์ƒ๊ณผ ๋‹ค๋ฅด๊ฒŒ getPokemonํ•จ์ˆ˜๊ฐ€ 0.3์ดˆ๋งˆ๋‹ค๊ฐ€ ์•„๋‹Œ input์˜ value๊ฐ€ ๋ฐ”๋€”๋•Œ๋งˆ๋‹ค ํ˜ธ์ถœ๋œ๋‹ค๋Š” ์ ์ด๋‹ค.

์ด ์ฝ”๋“œ์˜ ๋ฌธ์ œ์ ์€ setText ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•  ๋•Œ๋งˆ๋‹ค ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žฌ๋ Œ๋”๋ง๋˜์–ด debounceํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” getPokemonํ•จ์ˆ˜๋ฅผ ์žฌ์ƒ์„ฑํ•œ๋‹ค๋Š” ์ ์ด๋‹ค.
 

 4. ์ปดํฌ๋„ŒํŠธ ์žฌ๋ Œ๋”๋ง์— ๊ด€๊ณ„์—†์ด debounce ํ•จ์ˆ˜ ์‹คํ–‰ํ•˜๊ธฐ

const getPokemon = useCallback(debounce(async (value: string) => {
    await axios
      .get(`https://pokeapi.co/api/v2/pokemon/${value}`)
      .then((res) => {
        setPokemon(res);
      })
      .catch((err) => {
        return;
      });
  }, 300),
  []
;

const handleSearch = (e) => {
  setText(e.target.value);
  getPokemon(e.target.value);
}


์ •๋‹ต์€ useCallback ํ•จ์ˆ˜๋กœ debounceํ•จ์ˆ˜๋ฅผ ๊ฐ์‹ธ์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

์œ„์˜ getPokemon ํ•จ์ˆ˜๋Š” handleSearch์—์„œ text๊ฐ€ ๋ณ€๊ฒฝ์ด ๋˜์–ด๋„ ์ด ๋ณ€์ˆ˜๋ฅผ ๊ตฌ๋…ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— debounceํ•จ์ˆ˜๋ฅผ ์žฌ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค.



 

 

๐Ÿ„‍โ™€๏ธ input ํƒœ๊ทธ๋กœ ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•˜๊ฑฐ๋‚˜ ํŒŒ์ผ์˜ url์„ ๊ฐ€์ง€๊ณ  ์žˆ์„ ๊ฒฝ์šฐ ํŒŒ์ผ์˜ ํ™•์žฅ์ž๋ฅผ ์ œ๋Œ€๋กœ ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.

 

 

How to: ํŒŒ์ผ ์—…๋กœ๋“œ ํ›„ e.target.files์˜ name์„ ํ™œ์šฉ

<input type="file" id="avatar" name="avatar" accept="*" />

 

 

 

 

์œ„ ํŒŒ์ผ ๊ฐ์ฒด๋Š” inputํƒœ๊ทธ๋ฅผ ํ†ตํ•ด ํŒŒ์ผ์„ ์—…๋กœ๋“œ ํ•œ ํ›„ ์–ป๊ฒŒ ๋˜๋Š” ๊ฐ’์ด๋‹ค.

 

๊ทธ ์ค‘ name๊ฐ’์—๋Š” ํŒŒ์ผ์˜ ์ด๋ฆ„์ด ์กด์žฌํ•˜๋Š”๋ฐ ์ด๋ฅผ ํ™œ์šฉํ•ด ํ™•์žฅ์ž ๊ฐ’์„ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

<input
    type="file"
    id="upload"
    onChange={(e) => {
      const files = e.target.files;
      const filename = files[0].name;
      const splitedNameArr = filename.split('.');
      const lastSplitedVal = splitedNameArr.at(-1);

      console.log(lastSplitedVal);
    }}
  />

 

ํŒŒ์ผ name์—์„œ split์„ ํ†ตํ•ด . ์„ ๊ธฐ์ค€์œผ๋กœ ๋‚˜๋ˆˆ ๋’ค ๋งˆ์ง€๋ง‰ . ๋’ค์˜ ๊ฐ’์„ ํ™•์žฅ์ž๋กœ ์ธ์‹ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ํ™œ์šฉํ–ˆ๋‹ค.

 

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํŒŒ์ผ ์ด๋ฆ„ ์‚ฌ์ด์— . ์ด ์กด์žฌํ•˜๋”๋ผ๋„ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰ . ๋’ค ๊ฐ’์„ ํ™•์žฅ์ž๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

 

* Array.prototype.at() ๊ธฐ๋Šฅ์ด ๋„ˆ๋ฌด ๋ง˜์— ๋“ค์–ด ๋งํฌ ๋‚จ๊ธด๋‹ค!

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/at

+ Recent posts