React

React 리액트 state 기본 사용법

TASTY.K 2022. 8. 21. 23:44
반응형
김민준 저, 「리액트를 다루는 기술」 책을 보며 공부한 내용을 정리한 글입니다.

 

리액트 state란

 

리액트 컴포넌트 내부에서 변경할 수 있는 값

 

 



1. 클래스 컴포넌트에서 state

 

기본사항

 

  • (1) constructor 함수 쓰는 경우 => 클래스 constructor 안에 this.state = {} 형태로 선언
class MyCompo extends Component {
  
  constructor(props){
    super(props); // 노묻따 필수라인
    this.state = {
      state1: 초기값,
      state2: 초기값
    };
  };
  
  render(){ ... };  
}

 

  • (2) constructor 함수 안쓴다면 => 클래스 안에 state = {}; 형태로 선언

 

class MyCompo extends Component {

  state = {
    state1: 초기값,
    state2: 초기값
  };
  
  render(){ ... };
}

 

  • 이후 render() 함수 안에서 const { 스테이트1, 스테이트2, ... } = this.state 로 비구조 할당 사용 가능
  render(){
    const { state1, state2 } = this.state;
    return <>{state1}, {state2}</>;
  }

 

  • 값 변경시에는 setState를 쓰며, this.setState({ 스테이트명: 신규값 }) 형태로 사용 가능
render(){
  const { state1, state2 } = this.state;
  return({
    <>
      {state1}, {state2}
      <button onClick = { ()=>{ this.setState( {state1: '변신'} ); } }>변경</button>
    </>
  });
}

 

주의사항

 

  • 이벤트 하나당 setState를 여러번 사용할 때
this.setState는 비동기적으로 업데이트를 한다. 따라서 onClick같은 이벤트 하나에 setState가 여러번 들어간다면 하나 빼고 누락될 수 있다. 해결책은 기존처럼 변경될 객체값 this.setState()에 바로 넣지 않고, 함수를 넣어주는 것

 

  • 누락 에러 날 코드
onClick = { () => {
  this.setState(  { state1: state1 + 1 } );
  this.setState(  { state1: state1 + 1 } );
}}

 

  • 함수로 바꿔 해결한 코드
onClick = { () => {
  this.setState( preveState => {
    return { state1: prevState.state1 + 1 };
  });
  this.setState( preveState => {
    return { state1: prevState.state1 + 1 };
  });
}}

 

  • 위 코드에서 return 빼고 바로 실행하게 바꾼 모습 : 바로 실행이 필요할 때, setState 안 함수가 한줄일 때!
onClick = { () => {
  this.setState( preveState => ({ state1: prevState.state1 + 1 }) );
  this.setState( preveState => ({ state1: prevState.state1 + 1 }) );
}}



setState 후 특정 작업 실행

 

  • state 값을 바꿔준 뒤 특정 작업(함수)을 실행하고 싶을 때, setState의 두 번째 파라미터로 콜백(callback) 함수를 등록하여 작업을 처리할 수 있음
this.setState( { 바꿀 스테이트값 기술 }, () => { 여기 콜백 함수 } );

 

  • 코드 예제
onClick = { () => {
  this.setState( 
    { state1: state1 + 1 } , 
    () => {
      console.log('setState 호출');
      console.log( this.state.state1 );
    }
  );
}}

 

 

2. 함수형 컴포넌트에서 state

 

기본사항

  • 함수형 컴포넌트에서 state를 사용하려면 useState 함수를 써야 함
  • 그것도 리액트 16.8버전 이상에서만 가능
  • 이 과정에서 Hooks를 사용하게 됨
  • 배열 비구조화 할당 문법을 알아야 함
// 배열 비구조적 할당 ⭐️
const myArr = [1,2];
const [arrOne, arrTwo] = myArr;

// 위 코드는 아래와 같다
const myArr = [1,2];
const arrOne = myArr[0];
const arrTwo = myArr[1];


useState 사용 방법

 

  • useState 모듈 임포트
import {useState} from ‘react’;

 

  • 컴포넌트 함수 안에, return문 위에 다음과 같이 쓴다
  • const [스테이트이름, 세터이름] = useState(스테이트 디폴트값)
const [myState, setMyState] = useState(‘’);


예제

  • 부모 컴포넌트 (App.js)
import React from ‘react’;
import Coffee from ‘./Coffee’;

const App = () => {
  return <Coffee />;
}
export default App;

 

  • 자식 컴포넌트 (Coffee.js)
import React, {useState} from ‘react’;

const Coffee = () => {
  // state 1
  const [order, setOrder] = useState(‘’);
  const onClickAmeri = () => setOrder(‘아메리카노’);
  const onClickLatte = () => setOrder(‘카페라떼’);
  // state 2
  const [color, setColor] = useStste(‘black’);
  
  return(
    <div>
      <button onClick = {onClickAmeri}>아메리카노</button>
      <button onClick = {onClickLattr}>카페라떼</button>
      <p style={{color}}>{order} 주문되었습니다</p>
      
      // inline으로 함수 즉시 실행
      <buttonr style{{color: ‘red’}} onClick = {()=>setColor(‘red’)}>
      빨강
      </button>
      <buttonr style{{color: ‘blue’}} onClick = {()=>setColor(‘blue’)}>
      파랑
      </button>
    </div>
  )

}



3. 주의사항

 

클래스형, 함수형에 상관 없이 state 값을 바꿀 때에는 값에 바로 접근하여 바꾸지 않는다!! 반드시 setState 혹은 useState 를 사용하여 값을 바꾸어야 한다.

 

잘못된 코드 예시

// 클래스형 컴포넌트 잘못된 state 사용례
this.state.number = this.state.number + 1; 
this.state.array = this.array.push(2);
this.state.object.value = 5;

// 함수형 컴포넌트 잘못된 state 사용례
const [object, setObject] = useState({a:1, b:2});
object.b = 2;


배열/객체 업데이트시

 

객체 사본을 만들고 그 사본에 값을 업데이트한 후, 그 사본의 상태를 setState 혹은 세터 함수를 통해 업데이트함

 

  • 객체 사본을 만들 때에는 spread 연산자인 ... 을 사용
const obj = { a: 'a', b: 'b', c: 'c' } //오리지널 객체
const obj_edit = { ...obj, b: 'not b'} // b값만 바꿔주고 나머진 복제

 

  • 배열 사본 변경은 배열의 내장함수를 이용
let myArr = [
   { id:1, val: 0 },
   { id:2, val: 0 },
   { id:3, val: 0 }
]
// 카피
let myArr_copy = myArr;

// 항목 추가
myArr_copy = myArr_edit.concat( { id:4, val: 0 } )
// (id가 2인) 항목 제거
myArr_copy.filter( item => item.id !== 2 )  
// (id가 1인) 항목 값을 (1로) 변경
myArr_copy.map( item => ( item.id === 1? { ...item, value: 1 } : item ) );

// 대체 (리액트에선 setState 문법에 맞게 변경..)
myArr = myArr_copy;

 

반응형