React : useState 비동기(기본) 와 동기처리 feat. 함수 업데이트 초기화

[useState] – 동기/비동기
const [ value , SetValue ] = useState(초기값);

– useState 는 변수 업데이트 방식은 비동기 방식으로 처리된다
– useState 는 변수로 사용할 변수명 ‘value’ 와 변수를 업데이트 할 수 있는  ‘SetValue’ 로 정의된다.
★비동기 SetValue 는 직접 값을 업데이트 할 수 있으며, SetValue(100)  ,setValue (value + 1) 비동기로 작동한다.
★동기식 setValue (vals =>  vals + 1);  value 변수(최근값)을 인자 vals 로 받으며, callback 함수를 통해 업데이트 할 수 있다 

※ callback 함수를 인자로 작동되는 함수들은 모두 동기식으로 작동한다.

[useReducer] – 동기
callback 함수를 기본인자로 받아서 처리하는 useReducer 는  “동기식” 으로만 작동한다 (callback으로만 처리함)

const [ 상태변수 , 콜백함수 ] = userReducer( 콜백함수 , 상태 변수 초기값)
function 콜백함수(상태변수 , 콜백함수파라미터)

function myReducer(state , action)  
{     swtich( aciton.type)
     {
             case “INS” : 처리;  break;
     }   
}
const [ value , dispatch ] = useReducer( myReducer, 초기값); 

<button onClick={dispatch({ type : ‘INS’  , name : ‘test’})}>클릭</button>
(myReducer 의 콜백을 통해  “동기식” 으로 만 처리되는 useReducer)


– 동기화 처리를 하기위해서는 

   const [number , setNumber] = useState(0);

ㆍ useState 를 통한 number 초기화
     ① 값 초기화
          useState(0);    //  number 를 0 으로 초기화 하여 useState 생성      

     ② 함수 초기화
       function numbList() {           
                // db 처리 및 부하가 있는 작업
                return [1,2,3,4,5,6,7,8,9]
       };

      useState(numbList);      // numbList 함수를 전달하여 number 를 초기화 하여 useState 생성
      useState(numbList());    // numbList() 작성시 함수를 호출하면,  컴포넌트가 리렌더링 될때, 계속  numberList 호출함.

      이는 onClick 이벤트에 함수를 전달 해야되는데 함수를 실행하는 오류를 범하는것과 같은현상
      <button onClick={onClickAdd}>추가 </button>      //   button 의 onClick 이벤트에 함수를 전달, 클릭시 실행됨
      <button onClick={onClickAdd()}>추가 </button>   //  렌더링 될때마다 onClickAdd() 이벤트가 실행됨

     useState(numberList)  // 콜백용 함수를 ‘전달만’ 하여 , hook 을 통해 useState 이 생성될대 최초 1회만 호출하게 해야함 
                또는,

     useState(() => numberList());
    <button onClick={ () => onClickAdd() }></button>  


ㆍ 값 설정으로 number 업데이트 (비동기)
     setNumber(100);
     setNumber(number + 1);

ㆍ 함수를 통한 number  업데이트 (동기식)

     setNumber( (n) => { return ( n * 2) });    // n 은 number 의 최근 update 된 값

ㆍ setState 작동방식 (비동기식처리)

const [number ,setNumber] = useState(0);
setNumber(number  + 1); // number 에 +1 실행하여 number  업데이트 

1)  number 에 업데이트된 state 값으로 virtualDom 생성
2)  현재의 state 값의 element tree 와 virtualDom 비교
3) 업데이트가 필요한 state 에만 DOM 적용 후 렌더링

단 setState 가 연속으로 호출되면 batch update 후 실행
– batch update : 리액트 성능을 위해 여러개의 state 업데이트를 하나로 묶어서 리렌더링함
(단, 하나의 state에 여러번의 setState 값 update 를 실행한 경우가장 최신의 state 값만 적용)

< App.js >
import React from ‘react’
function App()

{
 
    const [num ,setNum] = useStats(0);
    function onClickAdd()

    {
            setNumber( num + 1)   // ① num = num + 1;  

            setNumber( num + 1)   // ② num = num + 1;  
            setNumber( num + 1)   // ③ num = num + 1 ; 
           // 결국 number 는 1    
           // batch update  : 단, 하나의 state에 여러번의 setState 값 update 를 실행한 경우가장 최신의 state 값만 적용       

    }

    return (
             <div>
                   <div>{number}</div>
                   <div><button onClick={onClickAdd}>더하기</button></div>
             </div>
       )

ㆍ setTimeout 으로 시간차를 주면 어떻게 될까? 

function add()
{
       setNumber(num + 1);  //  ①
       setTimeout( ()=>{
                setNumber(num + 100);  // ②    
        } , 1000)   
        
       // ① 번  실행    num =  1   출력, 
       // 1 초후

       // ② 번  실행    num  = 1  + 100 이 아니라  num 기존값 0  과 + 100 이되어 , 결국  100  출력
       // 결과 : 1 출력 –  1초후 –  100 출력함      

       // 계속 클릭할경우
       // ① 번  실행  num  = 100 + 1  , 101 출력
       // 1 초후
       // ② 번 실행  num  =101  + 100 이 아니라  num 기존값 100  과 + 100 이되어 , 결국  200  출력
       // 결과 : 101 출력 –  1초후 –  200 출력함

       // 결국 ① 의 실행은 무시되고 setState 값 업데이트 개념에 따라 ② 처리만 인정 ↓
       // batch update  : 단, 하나의 state에 여러번의 setState 값 update 를 실행한 경우가장 최신의 state 값만 적용       
}

ㆍ여러번의 setState update 값을 적용할 수 있는 (동기식처리)

setState hook의 update 함수의 2가지 옵션
const [number , setNumber] = useState();

① setNumber(value)      // 직접 값 변경
② setNumber(callback)  // 함수를 통한 변경(동기화처리)
    setNumber( (prevState) => { return prevState + 1 }  // 이때 인자prevState는 , 최신 업데이트된 number 값을 보유함

① 직접 값을 전달하여 number 에 업데이트
     setNumber(100);
     setNumber(number + 1);

② 함수를 통한 변경(동기화처리)
     setNumber( (prevState) => { return prevState + 1 } 

function add()
{
      setNumber( n => n + 1); // n 은 number 의 초기값 0  과 + 1 하여 number 를 1로 (동기화 처리함)
      setNumber( n => n + 1); // n 은 number 의 최근값 1  과 + 1 하여 number 를 2로 (동기화 처리함)
      setNumber( n => n + 1); // n 은 number 의 최근값 2  과 + 1 하여 number 를 3로 (동기화 처리함)

      // 함수형 업데이터를 통해 , batch update 및 비동처리대신  동기화 처리를 통해 같은 setState update 함수가 정상처리
      // 결과 정상적으로 number 는 3 이됨
}

 

 

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다