MapleStory Finger Point Cute Line Smiley Blinking Hello Kitty Angel MapleStory Finger Point

๐Ÿ’ŽReact

[React] React hook (ํ›…) , ๋ผ์ดํ”„ ์‚ฌ์ดํด

HYEJU01 2024. 8. 28. 20:27

1. ํ›…(HOOK) 

 

๐Ÿ˜บ ๋ฆฌ์•กํŠธ์—๋Š” hook ํ›… ์ด๋ผ๋Š” ๊ฐœ๋…์ด ์žˆ๋‹ค.

 

๐Ÿ“ Hook ์ด๋ž€? 

  1. ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๋Š” ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ(Class component)์™€ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ(Functional component)๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค.
  2. ๋ฆฌ์•กํŠธ ํ›…์€ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์œผ๋กœ React 16.8๋ฒ„์ „์— ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ๊ธฐ๋Šฅ
  3. ํ•จ์ˆ˜ํ˜•ํƒœ์˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ช‡๊ฐ€์ง€ ๊ธฐ์ˆ ์„ Hook์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. (useState, useEffect ๋“ฑ)
  4. ๋ฆฌ์•กํŠธ ํ›…์€ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

 

 

 

 

๐Ÿ˜บ ํ›…์—๋„ ๊ทœ์น™์ด ์žˆ๋‹ค ! 

 

๐Ÿ“ Hook ๊ทœ์น™

  • ์ตœ์ƒ์œ„ ์—์„œ๋งŒ Hook์„ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค
    • ๋ฐ˜๋ณต๋ฌธ, ์กฐ๊ฑด๋ฌธ, ์ค‘์ฒฉ๋œ ํ•จ์ˆ˜ ๋‚ด์—์„œ Hook์„ ์‹คํ–‰ํ•˜๋ฉด ์•ˆ๋œ๋‹ค.
    • ์ด ๊ทœ์น™์„ ๋”ฐ๋ฅด๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง๋  ๋•Œ๋งˆ๋‹ค ํ•ญ์ƒ ๋™์ผํ•œ ์ˆœ์„œ๋กœ Hook์ด ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์ด ๋ณด์žฅ๋œ๋‹ค.
  • ๋ฆฌ์•กํŠธ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ๋งŒ Hook์„ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.

 

 

 

 

 

๐Ÿ˜บ  ์ด์ œ ํ›… (hook) ์ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ๋Š”์ง€ ๋ด๋ณด์ž !

๊ธฐ๋ณธ ํ›…๋“ค์€ ๊ผญ ์•Œ์•„๋‘๋„๋ก ํ•˜์ž !

 

 

๐Ÿ“ ํ›… (hook) ์ข…๋ฅ˜

 

 

1. useState(์ดˆ๊ธฐ๊ฐ’)

 

useState() : ๋ฐฐ์—ด๋ฐ˜ํ™˜ ์ฒซ๋ฒˆ์งธ ๋ฐฐ์—ด์˜ ์š”์†Œ์—๋Š” ํ˜„์žฌ๊ฐ’์„, ๋‘๋ฒˆ์งธ ์š”์†Œ๋Š” ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” (setter) ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

const [data, setData] = useState('์ดˆ๊ธฐ๊ฐ’')

 

 

2. userEffect(์‹คํ–‰์‹œํ‚ฌ ์ฝœ๋ฐฑํ•จ์ˆ˜, ๊ฐ’์— ๋”ฐ๋ฅธ ๋ Œ๋”๋ง ์ง€์ •-๋ฐฐ์—ด)

ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ(side effects)๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ํ›…์ž…๋‹ˆ๋‹ค.

์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ž€ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง ๊ณผ์ • ์™ธ๋ถ€์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์ž‘์—…

 

 

3. useRef(์ดˆ๊ธฐ๊ฐ’)

ํŠน์ • ํƒœ๊ทธ์— ์ด๋ฆ„๋‹ฌ๊ธฐ

 

 

4. useReducer(๋ฆฌ๋“€์„œํ•จ์ˆ˜๋ช…, state๊ฐ’) 

์™ธ๋ถ€์—์„œ state์‚ฌ์šฉํ•˜๊ธฐ

 

 

๋“ฑ๋“ฑ....

 

 

์ปดํฌ๋„ŒํŠธ์˜ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™” ํ›… .... 

  • useMemo
  • useCallback

 

 


 

2. ๋ผ์ดํ”„ ์‚ฌ์ดํด  (ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ ๊ธฐ์ค€) - userEffect

 

 

 

 

๐Ÿ˜บ ๋ผ์ดํ”„ ์‚ฌ์ดํด์ด ๋ญ˜๊นŒ??

๋ง ๊ทธ๋Œ€๋กœ ์ƒ๋ช…์ฃผ๊ธฐ๋กœ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒ์„ฑ, ์—…๋ฐ์ดํŠธ, ์ œ๊ฑฐ ๋˜๋Š” ๊ณผ์ •์—์„œ

ํŠน์ • ๋ฉ”์„œ๋“œ๋“ค์ด ํ˜ธ์ถœ๋˜๋Š” ์‹œ์ ์„ ๋งํ•œ๋‹ค.

์ž ! ์ƒ๋ช… ์ฃผ๊ธฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ํ•จ์ˆ˜๋“ค์„ ์•Œ์•„๋ณด์ž.

 

 

 

 

 

 

๐Ÿ˜บ ๋ Œ๋”๋ง ์ดํ›„์— ์‹คํ–‰์‹œํ‚ฌ ์ž‘์—…์ด ์žˆ์œผ๋ฉด ์•„๋ž˜ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. (ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ ๊ธฐ์ค€)

 

๐Ÿ“ ์ปดํฌ๋„ŒํŠธ, ๋ผ์ดํ”„ ์‚ฌ์ดํด (ํด๋ž˜์Šคํ˜• ! )

 

  1. componentDidMount : ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ๋จ, ์ฆ‰ ์ปดํฌ๋„ŒํŠธ์˜ ์ฒซ๋ฒˆ์งธ ๋ Œ๋”๋ง์ด ๋งˆ์น˜๋ฉด ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ
    componentDidMount() {
      console.log('Component has been mounted');
    }


  2. componentDidUpdate : state์˜ ๋ณ€๊ฒฝ, props์˜ ๋ณ€๊ฒฝ ์ดํ›„ ์‹คํ–‰๋˜๋Š” ๋ฉ”์„œ๋“œ
    componentDidUpdate(prevProps, prevState, snapshot) {
      console.log('Component has been updated');
    }


  3. componentWillUnmount : ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋˜๊ธฐ์ง์ „(์–ธ๋งˆ์šดํŠธ) ์‹œ์ ์— ์‹คํ–‰๋˜๋Š” ๋ฉ”์„œ๋“œ
    componentWillUnmount() {
      console.log('Component will unmount');
    }


  4. ์ด์™ธ์—๋„ ์—ฌ๋Ÿฌ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค

 

 

 

 


 

 

๐Ÿ˜บ ์ด๋•Œ, ์œ„์— ์„ค๋ช…ํ•œ  componentDidMount  ๊ฐ™์€ ์นœ๊ตฌ๋“ค์€ ` ํด๋ž˜์Šคํ˜• ` ์—์„œ๋งŒ ์‚ฌ์šฉ๋œ๋‹ค.

`ํ•จ์ˆ˜ํ˜•` ๋„ ์•Œ์•„๋ณด์ž !!!! !!!! !!!! !!!! !!!!

 


๐Ÿ“userEffect(์‹คํ–‰์‹œํ‚ฌ ์ฝœ๋ฐฑํ•จ์ˆ˜, ๊ฐ’์— ๋”ฐ๋ฅธ ๋ Œ๋”๋ง ์ง€์ •-๋ฐฐ์—ด )

 

ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ(side effects)๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ํ›…์ž…๋‹ˆ๋‹ค.

์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ž€ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง ๊ณผ์ • ์™ธ๋ถ€์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์ž‘์—…

 

  1. userEffect์˜ ์ฒซ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์‹คํ–‰์‹œํ‚ฌ ์ฝœ๋ฐฑํ•จ์ˆ˜
  2. userEffect์˜ ๋‘๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋ฐฐ์—ด[]์„ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ •๊ฐ’์ด update ๋  ๋•Œ๋งŒ ์‹คํ–‰์‹œ์ผœ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. useEffect() ๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ๋ผ์ดํ”„ ์‚ฌ์ดํด์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ mount, mount์ดํ›„, unmount๋•Œ ๋งˆ๋‹ค ํŠน์ •์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  4. useEffect() ๋Š” ์—ฌ๋Ÿฌ๊ฐœ ์ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
  5. ๋ Œ๋”๋ง(ํ™”๋ฉด์„ ์ง€์› ๋‹ค ๋‹ค์‹œ์ƒ์„ฑ) ์€ ์•„๋ž˜์™€ ๊ฐ™์€ ์ƒํ™ฉ์— ๋ฐœ์ƒ๋ฉ๋‹ˆ๋‹ค.

 

 

๐Ÿ“ ์ปดํฌ๋„ŒํŠธ, ๋ผ์ดํ”„ ์‚ฌ์ดํด (ํ•จ์ˆ˜ํ˜•! )

 

1. ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ๋จ, ์ฆ‰ ์ปดํฌ๋„ŒํŠธ์˜ ์ฒซ๋ฒˆ์งธ ๋ Œ๋”๋ง์ด ๋งˆ์น˜๋ฉด ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ

useEffect( () => {
	console.log(`๋ Œ๋”๋ง์™„๋ฃŒ`);
});

 

useEffect( () => {
	console.log(`์ฒ˜์Œ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค`);
}, []);
//mount ์ดํ›„ ์—…๋ฐ์ดํŠธ ๋  ๋•Œ๋Š” ์‹คํ–‰๋˜์ง€ ์•Š์œผ๋ ค๋ฉด, ๋‘๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฐฐ์—ด๋ฅผ ์ค๋‹ˆ๋‹ค.

 

 

 

2. state์˜ ๋ณ€๊ฒฝ, props์˜ ๋ณ€๊ฒฝ ์ดํ›„ ์‹คํ–‰๋˜๋Š” ๋ฉ”์„œ๋“œ

const HookEffect = () => {
    //useState
    const[name, setName] = useState('');
    const handleName = (e) => {
        setName( e.target.value );
    }

    //ํŠน์ •๊ฐ’์ด ์—…๋ฐ์ดํŠธ ๋  ๋•Œ๋งŒ ์‹คํ–‰ํ•ด์ฃผ๋ ค๋ฉด ๋‘๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๊ฐ’์„ state๊ฐ’์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค
    useEffect( () => {
        console.log(`name์ด ์—…๋ฐ์ดํŠธ ์‹œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค`)
    }, [name]);

    return (
        <div>
            
            ์ด๋ฆ„:<input type="text" onChange={handleName}/><br/>
            ์ด๋ฆ„:{name}
        </div>
    )
}

export default HookEffect;

 

 

๐Ÿ˜บโ›” ์ฃผ์˜ )  userEffect์•ˆ์—์„œ ๊ฐ์ฒดํƒ€์ž… state๋ฅผ setStateํ•˜๋Š” ๊ฒฝ์šฐ ๋ฌดํ•œ๋ฃจํ”„์— ๋น ์งˆ ์ˆ˜ ์žˆ๋‹ค!

https://kinsta.com/knowledgebase/react-hook-useeffect-has-a-missing-dependency/

 

How To Fix the “React Hook useEffect Has a Missing Dependency” Error

Learn 3 different ways to fix the common error that developers encounter, the “React Hook useEffect has a missing dependency" error.

kinsta.com

 

 

3. unmount์ง์ „ - ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ™”๋ฉด์—์„œ ์‚ฌ๋ผ์ง€๊ธฐ ์ง์ „์— ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

const HookEffect = () => {
    //useState
    const[name, setName] = useState('');
    const handleName = (e) => {
        setName( e.target.value );
    }
    
	//useEffect    
    useEffect( () => {
        console.log(`name์ด ์—…๋ฐ์ดํŠธ ์‹œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค`)
        
        //unmount์ดํ›„ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
        return () => {
            console.log(`unmount์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.`);
        }
    }, [name]);

    return (
        <div>
            ์ด๋ฆ„:<input type="text" onChange={handleName}/><br/>
            ์ด๋ฆ„:{name}
        </div>
    )
}

export default HookEffect;

 

 

 

 

 


 

3. ํŠน์ • ํƒœ๊ทธ์— ์ด๋ฆ„๋‹ฌ๊ธฐ - useRef()

 

 

๐Ÿ˜บ  ์ด๋ฒคํŠธ ์‚ฌ์šฉํ•˜๋‹ค๋ณด๋ฉด ํŠน์ • ํƒœ๊ทธ์— ์ ‘๊ทผํ•ด์„œ ์ฒ˜๋ฆฌํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊ธด๋‹ค.

 

๋ฌด์กฐ๊ฑด state ๋กœ ๊ด€๋ฆฌ๋˜์–ด์•ผ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ๋ฐ

state ๋กœ ์ œ์–ด ์•ˆ๋˜๋Š” ์• ๋“ค์€ (๋‹ค์ด๋ ‰ํŠธ๋กœ) ๋“ค์–ด๊ฐ€์„œ ํ•ธ๋“ค๋ง์„ ํ•ด์ค€๋‹ค.

์ด๋•Œ ref ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

 

ref = {} ๋กœ ๋‹ค์ด๋ ‰ํŠธ๋กœ ๋ฐ”๋กœ ์ ‘๊ทผํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค :) 

 

 

 

๐Ÿ“ useRef() ํ›… 

 

useRef(์ดˆ๊ธฐ๊ฐ’)

const ์‚ฌ์šฉํ• ์ด๋ฆ„ = useRef(null);
  • ์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋‹ค ๋ณด๋ฉด ํŠน์ • ํƒœ๊ทธ์— ์ ‘๊ทผํ•ด์„œ ํ•ธ๋“ค๋ง ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค.
  • arrow function์— event ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ, ์ž์‹  ํƒœ๊ทธ์—๋Š” ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋‹ค๋ฅธ ํƒœ๊ทธ๋Š” ํ•ธ๋“ค๋ง ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
  • ์ด๋Ÿฐ๊ฒฝ์šฐ useRef() ํ›…์„ ์ด์šฉํ•ด์„œ ํŠน์ •ํƒœ๊ทธ์— ์ด๋ฆ„์„ ์ง€์ •ํ•˜๊ณ  ํ•ธ๋“ค๋ง ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • useRef๋Š” ์ดˆ๊ธฐ๊ฐ’์„ ๊ฐ์ฒด๋กœ( {current:vlue} ) ์ €์žฅํ•˜๊ธฐ๋•Œ๋ฌธ์—  ๋ณ€์ˆ˜๋ช….current๋กœ ํ˜„์žฌํƒœ๊ทธ์— ์ ‘๊ทผ ํ•  ์ˆ˜์žˆ์Šต๋‹ˆ๋‹ค.

 

import { useRef } from "react";

function HookRef(){

  let input = useRef(null);

  let handleClick = () => {
    // ๊ฐ’๋ณ€๊ฒฝ์€ state ๋กœ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ๊ฒƒ์ด๊ณ  (๋žœ๋”๋ง)
    //ref ๋Š” ํŠน๋ณ„ํ•œ ์ƒํ™ฉ์—์„œ๋งŒ ๊ฐ•์ œ๋ณ€๊ฒฝ ์„ ํ˜ธ๋˜์ง€์•Š์Œ (๋žœ๋”๋ง ์ผ์–ด๋‚˜์ง€ ์•Š์Œ
    //console.log(input);
    //console.log(input.current); // ํƒœ๊ทธ์— ๋‹ค์ด๋ ‰ํŠธ ์ ‘๊ทผ ๊ฐ€๋Šฅ
    console.log(input.current.type);
    console.log(input.current.value);

    input.current.focus();
  }

  return (

    <>
    <input type="text" ref={input}/>
    <button type="button" onClick={handleClick}> ๋“ฑ๋ก </button>    
    </>

  )

}

export default HookRef;

4. ์™ธ๋ถ€์—์„œ state์‚ฌ์šฉํ•˜๊ธฐ -  useReducer()

 

๐Ÿ˜บ state ๋ฅผ ์™ธ๋ถ€์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„๋•Œ์—๋Š” ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ?

useReducer() ํ›…์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค !

 

 

 

 

๐Ÿ“ useReducer() ํ›… 

  • useReducer๋Š” state์™€ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค.
  • useReducer๋Š” ์™ธ๋ถ€์—์„œ state๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
  • ๋ฆฌ๋“€์„œํ•จ์ˆ˜๋ฅผ ์™ธ๋ถ€๋กœ exportํ•˜๊ฒŒ ๋˜๋ฉด ๋กœ์ง์„ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (์žฌ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•ด์ง)
  • ์ฆ‰, ์™ธ๋ถ€์—์„œ state ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค. ์žฌํ™œ์šฉ์ด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.

 

const [ํ˜„์žฌ๊ฐ’, ๋ฆฌ๋“€์„œactionํ•จ์ˆ˜] = useReducer(๋ฆฌ๋“€์„œํ•จ์ˆ˜๋ช…, state๊ฐ’);

 

 

const ๋ฆฌ๋“€์„œํ•จ์ˆ˜๋ช… = (state๊ฐ’, ๋ฆฌ๋“€์„œactionํ•จ์ˆ˜๋กœ ์ „๋‹ฌํ•˜๋Š” ์ƒํƒœ๊ฐ’) => {
	//์ดˆ๊ธฐ๊ฐ’์„ action ์ƒํƒœ์— ๋”ฐ๋ผ์„œ ๋ณ€๊ฒฝ
	return state๊ฐ’
}

 

 

import { useReducer } from "react";

//์ปดํฌ๋„ŒํŠธ ์™ธ๋ถ€์— ์„ ์–ธ
//๋ฆฌ๋“€์„œ(์ƒํƒœ์ œ์–ด)๋Š” (ํ˜„์žฌstate, ๋ฆฌ๋“€์„œactionํ•จ์ˆ˜๋กœ ์ „๋‹ฌํ•˜๋Š” ์ƒํƒœ๊ฐ’) ๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค.
const myReducer = (state, action) => {

    if(action.type === 'increase') {
        state = { value: state.value+1 }
    } else if(action.type === 'decrease') {
        state = { value: state.value-1 }
    } else if(action.type === 'reset'){
        state = { value : 0}
    } 

    return state
}

const HookReducer = () => {

    //state์—์„œ ๋งŒ๋“ค์—ˆ๋˜ ์ฆ๊ฐ€,๊ฐ์†Œ ๋ฆฌ๋“€์„œ ์ ์šฉํ•˜๊ธฐ
    //1. const[state๊ฐ’ , ๋ฆฌ๋“€์„œ์‹คํ–‰ํ•จ์ˆ˜] useReducer( ๋ฆฌ๋“€์„œ, state์ดˆ๊ธฐ๊ฐ’)
    const [state, func] = useReducer(myReducer, {value:0 } )

    const handleIncrease = () => {
        func({type: 'increase'});
    }

    return (
        <div>
            <button type="button" onClick={ handleIncrease }>์ฆ๊ฐ€</button>
            <button type="button" onClick={ () => func({type: 'decrease'}) }>๊ฐ์†Œ</button>
            <button type="button" onClick={ () => func({type: 'reset'}) }>์ดˆ๊ธฐํ™”</button>
            <br/>
            ํ˜„์žฌ์นด์šดํŠธ {state.value}
        </div>
    )
}

export default HookReducer;

 

 

 

๐Ÿ“ useState์™€ useReducer์˜ ๋น„๊ต

  1. useState, useReducer ๋ชจ๋‘ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ํ›…์ž…๋‹ˆ๋‹ค.
  2. useState๋Š” ๊ด€๋ฆฌํ•  ์ƒํƒœ๊ฐ€ ๊ฐ„๋‹จํ•  ๋•Œ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹๋‹ค. (์‰ฝ๋‹ค)
  3. ๋ฐ˜๋ฉด ๊ด€๋ฆฌํ•  ์ƒํƒœ๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ์ด๊ณ , ์„œ๋กœ๊ฐ€ ์˜์กดํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ์ƒํƒœ๋ฅผ ์กฐ์ž‘ํ•  ๋™์ž‘์ด ์—ฌ๋Ÿฌ๊ฐœ์ผ ๋•Œ๋Š” useReducer๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. (์–ด๋ ต๋‹ค)
  4. ๋ฐ˜๋“œ์‹œ useReducer๋ฅผ ์จ์•ผํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. useState๊ฐ€ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

 

 

 

 


 

[App.js]

import HookEffect from "./hook/HookEffect.js";
import HookQ2 from "./hook/HookQ2.js";
import HookReducer from "./hook/HookReducer.js";
import HookReducer2 from "./hook/HookReducer2.js";
import HookRef from "./hook/HookRef.js";

function App(){
  return (
    <>
    <HookEffect />
    
    <hr />
    <HookRef />

    <hr />
    <HookReducer />

    <hr />
    <HookReducer2 />

    <hr/>
    <HookQ2 />
    </>
  )
}

export default App;

 

 

 

[HookEffect.js]

import {useEffect, useState} from 'react';

function HookEffect() {

  //useStateํ›…
  const [data, setData] = useState('');
  const [age, setAge] = useState('');

  //useEffectํ›… => ์ปดํฌ๋„ŒํŠธ ๋ผ์ดํ”„์‚ฌ์ดํด ๊ด€๋ฆฌ
  useEffect( () => {
    console.log('๋งˆ์šด๋“œ ์ดํ›„์— ๋™์ž‘๋จ(๋ Œ๋”๋ง ์ดํ›„์— ๋™์ž‘)');
  })

  // useEffect( () => {
  //   console.log('๋งˆ์šด๋“œ ์ดํ›„์— ๋”ฑ ํ•œ๋ฒˆ๋งŒ ์‹คํ–‰๋จ(๋„คํŠธ์›Œํฌ์ƒ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ ์˜ฌ๋•Œ ์‚ฌ์šฉํ•จ)');
  // }, []);

  // useEffect( () => {
  //   console.log('ํŠน์ • ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์„œ ๋ Œ๋”๋ง ๋ ๋•Œ ๋™์ž‘๋จ(ํŠน์ • state๊ฐ€ ๋ณ€๊ฒฝ๋ ๋•Œ๋งŒ ์‹คํ–‰๋จ)');
  // }, [data, age]); 

  // useEffect( () => {
  //   console.log('effect์‹คํ–‰๋จ~');
  //   return () => {
  //     console.log('unmount(์†Œ๋ฉธ) ๋˜๊ธฐ์ „์— ์‹คํ–‰๋จ');
  //   }
  // }, [data]); //data๊ฐ€ ๋ณ€๊ฒฝ๋ ๋•Œ๋งŒ.
  
  //useEffect๋Š” ์—ฌ๋Ÿฌ๊ฐœ ์ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
  // useEffect( () => {
  //   console.log('effect์‹คํ–‰๋จ22222~~');
  // });


  //๋ฌดํ•œ๋ฃจํ”„์— ๋น ์งˆ ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ
  // const [ex, setEx] = useState({name : 'ํ™๊ธธ๋™'});
  // useEffect( () => {
  //   let copy = {...ex};
  //   setEx(copy);
  // }, [ex]); 





  console.log('์ฝ”๋“œ ์‹คํ–‰๋จ..');

  return (
    <>
      <input type="text" value={data} onChange={ (e) => setData(e.target.value) } />
      <br />
      <input type="text" value={age} onChange={ (e) => setAge(e.target.value) }/>
      data : {data} ,  age : {age}

    </>
  )
}

export default HookEffect;

 

 

 

  useEffect( () => {
    console.log('๋งˆ์šด๋“œ ์ดํ›„์— ๋™์ž‘๋จ(๋ Œ๋”๋ง ์ดํ›„์— ๋™์ž‘)');
  })

 


 

  useEffect( () => {
    console.log('๋งˆ์šด๋“œ ์ดํ›„์— ๋”ฑ ํ•œ๋ฒˆ๋งŒ ์‹คํ–‰๋จ(๋„คํŠธ์›Œํฌ์ƒ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ ์˜ฌ๋•Œ ์‚ฌ์šฉํ•จ)');
  }, []);

 

 

 

  useEffect( () => {
    console.log('ํŠน์ • ๊ฐ’์ด ๋ณ€๊ฒฝ๋ผ์„œ ๋ Œ๋”๋ง ๋ ๋•Œ ๋™์ž‘๋จ(ํŠน์ • state๊ฐ€ ๋ณ€๊ฒฝ๋ ๋•Œ๋งŒ ์‹คํ–‰๋จ)');
  }, [data]);
  • data ๊ฐ’์ด ๋ณ€๊ฒฝ๋ ๋•Œ๋งŒ ์‹คํ–‰๋œ๋‹ค.

 


  useEffect( () => {
    console.log('effect์‹คํ–‰๋จ~');
  });
  
   useEffect( () => {
    console.log('effect์‹คํ–‰๋จ22222~~');
  });
  •  useEffect ๋Š” ์—ฌ๋Ÿฌ๊ฐœ ์กด์žฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 


 

  //๋ฌดํ•œ๋ฃจํ”„์— ๋น ์งˆ ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ
  const [ex, setEx] = useState({name : 'ํ™๊ธธ๋™'});
  useEffect( () => {
    let copy = {...ex};
    setEx(copy);
  }, [ex]);
  • ํ•ด๋‹น ์ฝ”๋“œ๋Š” ๋ฌดํ•œ๋ฃจํ”„์— ๊ฑธ๋ฆฌ๊ฒŒ๋œ๋‹ค. 
  • useEfftect() ๋Š” ex ๊ฐ€ ๋ณ€๊ฒฝ๋ ๋•Œ ๋งˆ๋‹ค ์‹คํ–‰๋œ๋‹ค. => ํ•˜์ง€๋งŒ setEx() ๊ฐ€ ๊ณ„์†ํ•ด์„œ ์‹คํ–‰๋˜๋ฉด์„œ ex ๊ฐ€ ๊ณ„์† ๋ฐ”๋€Œ๋ฏ€๋กœ ๋ฌดํ•œ๋ฃจํ”„๊ฒŒ ๊ฑธ๋ฆฌ๊ฒŒ ๋œ๋‹ค.

 


 

useEffect(() => {
  let copy = { ...ex };
  
  // ์ƒํƒœ๊ฐ€ ์‹ค์ œ๋กœ ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ์—๋งŒ ์—…๋ฐ์ดํŠธ
  if (JSON.stringify(copy) !== JSON.stringify(ex)) {
    setEx(copy);
  }
}, [ex]);
  • ์ด๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” ์œ„์™€ ๊ฐ™์ด ์กฐ๊ฑด๋ฌธ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ฃผ๋Š”๊ฒŒ ๋ฌดํ•œ๋ฃจํ”„๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š”๋ฐ ๋„์›€์ด ๋œ๋‹ค.

 


 

 

[HookRef.js]

import { useRef } from "react";

function HookRef(){

  let input = useRef(null);

  let handleClick = () => {
    // ๊ฐ’๋ณ€๊ฒฝ์€ state ๋กœ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ๊ฒƒ์ด๊ณ  (๋žœ๋”๋ง)
    //ref ๋Š” ํŠน๋ณ„ํ•œ ์ƒํ™ฉ์—์„œ๋งŒ ๊ฐ•์ œ๋ณ€๊ฒฝ ์„ ํ˜ธ๋˜์ง€์•Š์Œ (๋žœ๋”๋ง ์ผ์–ด๋‚˜์ง€ ์•Š์Œ
    //console.log(input);
    //console.log(input.current); // ํƒœ๊ทธ์— ๋‹ค์ด๋ ‰ํŠธ ์ ‘๊ทผ ๊ฐ€๋Šฅ
    console.log(input.current.type);
    console.log(input.current.value);

    input.current.focus();
  }

  return (

    <>
    <input type="text" ref={input}/>
    <button type="button" onClick={handleClick}> ๋“ฑ๋ก </button>    
    </>

  )

}

export default HookRef;

 

 

  let input = useRef(null);
  • useRef ๋ฅผ ํ†ตํ•ด input ์ด๋ผ๋Š” ์ฐธ์กฐ์ƒ์„ฑ

 

console.log(input.current); // ํƒœ๊ทธ์— ๋‹ค์ด๋ ‰ํŠธ ์ ‘๊ทผ ๊ฐ€๋Šฅ
console.log(input.current.type);
console.log(input.current.value);
  • useRef ๋ฅผ ํ†ตํ•ด์„œ ํƒœ๊ทธ์— ๋‹ค์ด๋ ‰ํŠธํ•œ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

 


 

[HookReducer.js]

 

import { useReducer } from "react";
import { myReducer } from "../util/MyReducer";

function HookReducer() {

  // // ๋ฆฌ๋“€์„œ ํ•จ์ˆ˜๋Š” ์ปดํฌ๋„ŒํŠธ ์™ธ๋ถ€์—์„œ ์ƒํƒœ ๊ฐ’์„ ๋ฐ›์•„์„œ state ์ฒด์ธ์ง€ !!!!!!!!!!!!!!!!!!!!
  // const myReducer = (state, action) => {
  //   console.log(state);
  //   console.log(action);

   if (action === "handleIncrease"){
     state = {value : state.value + 1}; // state ๋ฅผ ๋ฐ–์—์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ๋จ 
   }else if (action === "decrease") {
     state = {value : state.value - 1};
   }else if (action === "reset") {
     state = {value : 0};
   }
    

  //   return state;//๋ฐ˜ํ™˜๋˜๋Š” state ๋Š” reducer ์ƒํƒœ๊ฐ’์œผ๋กœ ๋‹ค์‹œ ๋ฐ˜ํ™˜๋จ
  // }; //state ๊ฐ’ , action (์ƒํƒœ๊ฐ’)


  const handleIncrease = () => {
    actionFunc("handleIncrease"); // myReducer ํ•จ์ˆ˜๋กœ action ๋“ค์–ด๊ฐ
  }

  //const result = useReduce(myReducer,{value: 0} ); //๋ฆฌ๋“€์„œ ํ•จ์ˆ˜ ,์ดˆ๊ธฐ๊ฐ’
  // ๋ฐ˜ํ™˜, state ๊ฐ’, reducerํ•จ์ˆ˜์˜ ์ƒํƒœ๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋Š” action ํ•จ์ˆ˜
  const [state, actionFunc] = useReducer(myReducer,{value: 0} ); //๋ฆฌ๋“€์„œ ํ•จ์ˆ˜ ,์ดˆ๊ธฐ๊ฐ’
  //console.log(result);

  return (

  <>

    <h3> useReducer</h3>
    
    ๋ฆฌ๋“€์„œ๋กœ ๊ด€๋ฆฌ๋˜๋Š” state ๊ฐ’ {state.value}

    <button type="button" onClick={handleIncrease} > ์ฆ๊ฐ€ </button>
    <button type="button" onClick={() => actionFunc("decrease")} > ๊ฐ์†Œ </button>
    <button type="button" onClick={() => actionFunc("reset")} > ์ดˆ๊ธฐํ™” </button>
  </>

  )
}

export default HookReducer;

 

 

 

const myReducer = (state, action) => {
console.log(state);
console.log(action);

return state;//๋ฐ˜ํ™˜๋˜๋Š” state ๋Š” reducer ์ƒํƒœ๊ฐ’์œผ๋กœ ๋‹ค์‹œ ๋ฐ˜ํ™˜๋จ
}; //state ๊ฐ’ , action (์ƒํƒœ๊ฐ’)

//----------
   
const [state, actionFunc] = useReducer(myReducer,{value: 0} ); //๋ฆฌ๋“€์„œ ํ•จ์ˆ˜ ,์ดˆ๊ธฐ๊ฐ’
 
 
 //----------
<h3> useReducer </h3>
๋ฆฌ๋“€์„œ๋กœ ๊ด€๋ฆฌ๋˜๋Š” state ๊ฐ’ {state.value}
  • myReducer ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ํ›…์œผ๋กœ ์œ„์™€ ๊ฐ™์ด state, aciton ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง„๋‹ค.
  • ์ฒซ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜ : ๋ฆฌ๋“€์„œ ํ•จ์ˆ˜๋กœ, ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋กœ์ง์ด๋‹ค! (state ๊ฐ’์€ ๋‹ค์‹œ reducer ์ƒํƒœ ๊ฐ’์œผ๋กœ ๋ฐ˜ํ™˜๋จ)

 

  • state: ํ˜„์žฌ ์ƒํƒœ ๊ฐ์ฒด
  • action: ์ƒํƒœ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ณ€๊ฒฝํ• ์ง€์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ๊ฐ์ฒด

 


 

๋ฆฌ๋“€์„œ๋กœ ๊ด€๋ฆฌ๋˜๋Š” state ๊ฐ’ {state.value}
<button type="button" onClick={handleIncrease} > ์ฆ๊ฐ€ </button>
<button type="button" onClick={() => actionFunc("decrease")} > ๊ฐ์†Œ </button>
<button type="button" onClick={() => actionFunc("reset")} > ์ดˆ๊ธฐํ™” </button>
  • ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด value ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๊ฒŒ ํ•  ๊ฒƒ ์ด๋‹ค.!

 

  const handleIncrease = () => {
    actionFunc("handleIncrease"); // myReducer ํ•จ์ˆ˜๋กœ action ๋“ค์–ด๊ฐ
  }
  
//onClick={() => actionFunc("decrease")}
  // ์š”๊ฑฐ๋ž‘ ๊ฐ™๋‹ค
  
  
    
const [state, actionFunc] = useReducer(myReducer,{value: 0} ); //๋ฆฌ๋“€์„œ ํ•จ์ˆ˜ ,์ดˆ๊ธฐ๊ฐ’
// actionFunc ๋กœ ๋“ค์–ด๊ฐ€๊ฒŒ๋œ๋‹ค
  • actionFunc ์€  handleIncrease or decrease ์™€ ๊ฐ™์€ ์ƒํƒœ ๊ฐ’์„ ๋ฐ›๋Š”๋‹ค.

 

 

  // ๋ฆฌ๋“€์„œ ํ•จ์ˆ˜๋Š” ์ปดํฌ๋„ŒํŠธ ์™ธ๋ถ€์—์„œ ์ƒํƒœ ๊ฐ’์„ ๋ฐ›์•„์„œ state ์ฒด์ธ์ง€ !!!!!!!!!!!!!!!!!!!!
  const myReducer = (state, action) => {
    console.log(state);
    console.log(action);

    if (action === "handleIncrease"){
      state = {value : state.value + 1}; // state ๋ฅผ ๋ฐ–์—์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ๋จ 
    }else if (action === "decrease") {
      state = {value : state.value - 1};
    }else if (action === "reset") {
      state = {value : 0};
    }

    return state;//๋ฐ˜ํ™˜๋˜๋Š” state ๋Š” reducer ์ƒํƒœ๊ฐ’์œผ๋กœ ๋‹ค์‹œ ๋ฐ˜ํ™˜๋จ
  }; //state ๊ฐ’ , action (์ƒํƒœ๊ฐ’)
  • ๋ฐ›์•„์˜จ ์ƒํƒœ๊ฐ’์„ ๋น„๊ตํ•ด์„œ state ๊ฐ’์„ ๋ณ€๊ฒฝ์‹œ์ผœ์ค€๋‹ค.
  • ์ดํ›„ state ๊ฐ’์„ ๋‹ค์‹œ ๋ฐ˜ํ™˜์‹œ์ผœ์ค€๋‹ค !

 

 


[HookReducer2.js]

import { useReducer } from "react";

function HookReducer2(){


  const nameReducer = (state, action) => {
    //action์— ์ „๋‹ฌ๋˜๋Š” ๊ฐ’์„ ์—˜๋ฆฌ๋จผํŠธ
   state = {...state, [action.name] : action.value};
    return state;
  }


  const [state, action] = useReducer(nameReducer,{name:'', age: 0} ); //๋ฆฌ๋“€์„œ ํ•จ์ˆ˜ ,์ดˆ๊ธฐ๊ฐ’

  return (
    <>

    <input type="text" name="name" value={state.name} onChange={(e)=>action(e.target)}/>
    <input type="number" name="age" value={state.age} onChange={(e)=>action(e.target)}/>

    ๋ฆฌ๋“€์„œ๋ฅผ ํ†ตํ•ด์„ญ ๋ณ€๊ฒฝ๋œ ๊ฐ’ : {state.name} {state.age}

    </>
  )
}
export default HookReducer2;

 

 

  const [state, action] = useReducer(nameReducer,{name:'', age: 0} ); //๋ฆฌ๋“€์„œ ํ•จ์ˆ˜ ,์ดˆ๊ธฐ๊ฐ’
  • ๋ฆฌ๋“€์„œํ•จ์ˆ˜์™€ ์ดˆ๊ธฐ๊ฐ’์„ ์ง€์ •ํ•ด์ค€๋‹ค. (state ์™€ action ์œผ๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค)
  • ์ฆ‰ name ์€ ๋นˆ๊ฐ’ , age ๋Š” 0 ์ด ์ดˆ๊ธฐ๊ฐ’์œผ๋กœ ์„ค์ •๋œ๋‹ค.

 

    const nameReducer = (state, action) => {
    //action์— ์ „๋‹ฌ๋˜๋Š” ๊ฐ’์„ ์—˜๋ฆฌ๋จผํŠธ
   state = {...state, [action.name] : action.value};
    return state;
  }
  • state ๊ฐ’์„ ๋ณต์‚ฌํ•ด์™€์„œ, action.name ์˜ ๊ฐ’๋งŒ ๋ณ€๊ฒฝํ•ด์ฃผ๊ณ  state ๋ฅผ ๋ฐ˜ํ™˜์‹œํ‚ค๋ฉด
  • ๋‹ค์‹œ name ๊ณผ age ๊ฐ’์ด ์ดˆ๊ธฐ๊ฐ’์œผ๋กœ ์„ค์ •๋œ๋‹ค.

 

 


 

[HookQ2.js]

import { useReducer, useRef, useState } from "react";

const HookQ2 = () => {

const [data, setData] = useState({todo:'', list : []});

const handleTodo = (e) => {
  setData({...data, ["todo"] : e.target.value})
}


//ref
let input = useRef(null);

let handleClick = () => {
  let newList = data.list;
  newList.push(data.todo);
  setData({todo: '', list : newList});
  
  input.current.focus();
}

return (

  <div>
    <input type="text" name="todo" placeholder="ํ• ์ผ ๋ชฉ๋ก ์ž‘์„ฑ" ref={input} value={data.todo} onChange={handleTodo}/>
    <button type="button" onClick={handleClick}> ๋“ฑ๋ก </button>
    <ul> 
      {
      data.list.map((item,index) => <li key="index"> {index+1}. {item} </li>)
      }
    </ul>

  </div>

)


}

export default HookQ2;

 

 

 

const [data, setData] = useState({todo:'', list : []});

const handleTodo = (e) => {
  setData({...data, ["todo"] : e.target.value})
}
  • todo, list ๊ฐ์ฒด ์ƒ์„ฑ, ์ƒํƒœ๊ด€๋ฆฌ!
  • handleTodo ๊ฐ€ ์‹คํ–‰๋˜๋ฉด , todo ๊ฐ’์ด input ๊ฐ’์œผ๋กœ ์—…๋ฐ์ดํŠธ ๋œ๋‹ค.

 

 

 

<input type="text" name="todo" placeholder="ํ• ์ผ ๋ชฉ๋ก ์ž‘์„ฑ" ref={input} value={data.todo} onChange={handleTodo}/>
<button type="button" onClick={handleClick}> ๋“ฑ๋ก </button>
<ul> 
  {
  data.list.map((item,index) => <li key="index"> {index+1}. {item} </li>)
  }
</ul>

 

  • ref ๋Š” useRef ๋ฅผ ํ†ตํ•ด input ์— ํฌ์ปค์Šค๋ฅผ ๋งž์ถฐ์ฃผ๊ธฐ ์œ„ํ•จ์ด๋‹ค.

 

 

let input = useRef(null);

let handleClick = () => {
  let newList = data.list;
  newList.push(data.todo);
  setData({todo: '', list : newList});
  
  input.current.focus();
}
  • handClick ์ด ์ž‘๋™ํ•˜๋ฉด newList์— todo ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  setData ๋กœ list ๋ฅผ newList๋กœ ์—…๋ฐ์ดํŠธ ์‹œ์ผœ์ค€๋‹ค.
  • input.current.focus(); ๋กœ input ์— ํฌ์ปค์Šค๋ฅผ ๋งž์ถฐ์ค€๋‹ค.