개발노트

2. Hooks 본문

React/basic

2. Hooks

aloha2jh 2020. 7. 14. 21:56

함수형 컴포넌트에서도 state , ref를 쓸수있게 됨 

 

함수형 컴포넌트에서의 state 사용은?

//기존 클래스 컴포넌트의 state선언 부분
  this.state={   
    firstNum : Math.ceil( Math.random() *9 ),
    secondNum : Math.ceil( Math.random() *9 ),
    value:'',
    result:'',
  }
  
  
  
 // 함수형 컴포넌트
 const Gugudan = () =>{

  // state를 선언하는 방법
  const[ firstNum, setFirstNum ] = React.useState( Math.ceil(Math.randaom()*9 ));
  const[ secondNum, setSecondNum ] = React.useState( Math.ceil(Math.randaom()*9 ));
  const[ value, setvalue ] = React.useState('');
  const[ result, setResult ] = React.useState(''); 

  return <div>Hi Hooks</div>;
}

-useState를 사용 

-클래스에서 하나씩 분리하였다.

-각각 전용 setState 가 있음  (비구조화 할당)

-( state는 컴포넌트안에 선언되어야한다 )

 

++

// 기존 클래스형 컴포넌트 렌더링 부분
 
 <React.Fragment>
   <p>{this.state.firstNum}곱하기 {this.state.secondNum}는?</p>
   <form onSubmit={this.guguCheck}> 
   <input   ref={ this.refInput }  type="number" value={this.state.value} 
   onChange={ this.inputChange } />
   </form>
   <p>{this.state.result}</p>
 </React.Fragment>
 
  
  //함수형 컴포넌트 
  <React.Fragment>
    <p>{firstNum}곱하기 {secondNum}는?</p>
    <form onSubmit={ guguCheck }> 
    <input   ref={ refInput }  type="number" value={value} 
    onChange={ inputChange } />
    </form>
    <p>{result}</p>
  </React.Fragment> 

const로 선언해서 {this.firstNum} 에서 {firstNum}

 

 

그렇다면 onClick, onChange, ref 같은 이벤트와 연결된 함수를 

클래스의 메서드로 표현했던 부분은?

  //클래스 컴포넌트 - 메서드
  inputChange = (e) =>{
   	this.setState( { value: e.target.value }  )
   }
   
  // 함수컴포넌트 - 함수
  const inputChange = (e) =>{
  	setValue(e.target.value);
  }

state와 마찬가지로 함수로 할당해줌

하지만 setState 할때는 각 알맞는 set(   )를 해준다.

 

//클래스컴포넌트
guguCheck = (e) => {
     e.preventDefault();

    if( parseInt(this.state.value) === this.state.firstNum*this.state.secondNum){
      this.setState( (prevState) => {
        return {
            result:`${prevState.value} : correct`,
            firstNum: Math.ceil( Math.random() * 9 ),
            secondNum: Math.ceil( Math.random() * 9),
            value:''
         }
      })
      this.focusInput.focus();

    }else{
      this.setState({
      result:'try again',
      value:''
      })
      this.focusInput.focus();
    }
}

이 부분도 마찬가지로

//함수형 컴포넌트
const guguCheck = (e) =>{
  e.preventDefault();

  if( parseInt(value) === firstNum*secondNum){

      setResult( ` : collect` );
      setFirstNum( Math.ceil( Math.random() * 9) );
      setSecondNum( Math.ceil( Math.random() * 9) );
      setValue('');

      //this.focusInput.focus();
      inputRef.current.focus();
   }else{

      setResult('try again');
      setValue('');
      inputRef.current.focus();
  }
}

 

ref = {} 부분은?

const inputRef = React.useRef(null);

 

useRef를 써서 DOM에 접근한다

 

//this.focusInput.focus();
inputRef.current.focus();


//focusInput;  
//refInput = (c) =>{
//	this.focusInput = c;  
//}

사용시에도 current붙여서 쓰면 된다

 

 

문제점 & 방안

state가 바뀔때마다 함수자체가 통째로 다시실행됨, 더 느림

=>최적화.. 과정 거쳐야 된다.

 

class 문과 집합class 와 이름이 겹치는 문제

=>class (.)를 쓰려면 className이라고 해야된다

 

<form for=''> 도 반복문 for 와 겹쳐서 htmlFor

 

 

<html lang="ko">
    <head>
        <meta charset="utf-8">
        <title>study</title>
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> 
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
      
    </head>
    <body>
        <div id="root"></div>
        <script type="text/babel"> 
            
            const Gugudan = () =>{

                const[ firstNum, setFirstNum ] = React.useState( Math.ceil(Math.random()*9 ));
                const[ secondNum, setSecondNum ] = React.useState( Math.ceil(Math.random()*9 ));
                const[ value, setValue ] = React.useState('');
                const[ result, setResult ] = React.useState(''); 
                const inputRef = React.useRef(null);

                const guguCheck = (e) =>{
                    e.preventDefault();
     
                    if( parseInt(value) === firstNum*secondNum){
                       
                        setResult( `  : correct` );
                        setFirstNum( Math.ceil( Math.random() * 9) );
                        setSecondNum( Math.ceil( Math.random() * 9) );
                        setValue('');
                         
                        //this.focusInput.focus();
                        inputRef.current.focus();
                    }else{
                        
                        setResult('try again');
                        setValue('');
                        inputRef.current.focus();
                    }
                }

                const inputChange = (e) =>{
                    setValue(e.target.value);
                }

                

                return (
                    <React.Fragment>
                        <p>{firstNum}곱하기 {secondNum}는?</p>
                        <form onSubmit={ guguCheck }> 
                            <input   ref={ inputRef }  type="number" value={value} 
                                onChange={ inputChange } />
                        </form>
                        <p>{result}</p>
                    </React.Fragment> 
                );
            }
        </script> 

        
        <script type="text/babel">  
            ReactDOM.render( <Gugudan /> , document.querySelector('#root') );    
        </script>
    </body>
</html>

'React > basic' 카테고리의 다른 글

3. (2)babel  (0) 2020.07.15
3. (1)webpack  (0) 2020.07.14
1. (3) 구구단게임  (0) 2020.07.14
1. (2)HTML속성, 상태(State), JSX  (0) 2020.07.13
1. (1)react component  (0) 2020.07.13