[새싹 프론트엔드] state

Ryu·2022년 11월 28일
0

새싹

목록 보기
21/36

state

state란?

state

  • 값을 저장하거나 변경할 수 있는 객체
  • 컴포넌트 내부에서 바뀔 수 있는 값을 의미
  • 주로 버튼 클릭과 같은 이벤트와 함께 사용함
  • props와 차이점
    • props는 부모 컴포넌트가 설정한 값을 전달받아 읽기 전용으로만 사용할 수 있음
    • props는 컴포넌트 내부에서는 값을 직접 변경할 수 없음
  • 값이 계속 변해야 하는 댓글창이나 쇼핑몰 장바구니 등에 사용
  • 값이 바뀌었다고 해서 컴포넌트를 다시 실행하지는 않음(그래서 값은 변경되지만 화면은 그대로 출력)

state 종류

  • 클래스형 컴포넌트의 state 속성
  • 함수형 컴포넌트의 useState 함수

함수형 컴포넌트의 useState

useState 사용하기

  • 배열 비구조화 할당
    • 배열 안에 들어있는 값을 쉽게 추출할 수 있도록 해주는 문법

    • array 안에 있는 값을 변수 one과 two에 저장

      const array = [1, 2];
      const one = array[0];
      const two = array[1];
    • 배열 비구조화 할당을 사용하여 저장

      const array = [1, 2];
      const [one, two] = array;
  • useState 함수
const [value, setValue] = useState();
  • 값의 형태
    • 숫자, 문자열, 객체, 배열
  • 리턴값
    • 배열
    • 첫 번째 원소: 현재 상태
    • 두 번째 원소: 상태를 바꾸어 주는 함수
  • useState 함수
// 인사의 초기값: 안녕하세요
const [인사, 인사변경] = useState('안녕하세요');
  • 값의 형태
    • 문자열
  • 리턴값
    • 배열
    • 첫 번째 원소: ‘안녕하세요’
    • 두 번째 원소: ‘안녕하세요’를 다른 값으로 바꾸어 주는 함수

state와 이벤트 연동

state와 클릭 이벤트 연동

<button onClick={클릭할때_실행할_함수}>클릭</button>
  • 함수 구현
function 클릭할때_실행할_함수(){
	// 실행할 내용
}

state 값 변경하기

state 값 변경

  • useState 함수 리턴값의 두 번째 원소를 이용
const [value, setValue] = useState('안녕하세요');
  • 아래와 같은 방식으로 값 변경 불가능
value = '반가워요';
  • setValue() 함수를 이용하여 값 변경
setValue('반가워요');

객체 또는 배열의 state 값 변경

  • 객체 또는 배열의 복사본을 만들어 값을 업데이트한 후, 복사본의 상태를 useState() 함수를 통해 업데이트
const [value, setValue] = useState({a:1, b:1});
  • 아래와 같은 방식으로 값 변경하면 안됨
value.b = 2;

객체/배열에 대한 사본 만들기

  • spread 연산자(…) 사용
    • 객체/배열의 기존 내용을 변경하지 않고도 새로운 객체/배열을 생성할 수 있음

    • 예) 객체 사본 만들기

      const object = { a : 1, b : 2, c : 3 };
      
      // object 객체의 사본 생성 후, b값만 변경
      const copyObject = { …object, b : 50 };
      
      console.log(copyObject); // { a : 1, b : 50, c : 3 }

[실습] spread 연산자

  • Spread.js
import React from 'react';

function Spread(){
	const person1 = { name : 'sooa' };
	const person2 = { name : 'sooa', age : 20 };
	const person3 = { name : 'sooa', age : 20, region : 'seoul' };
	
	return (
		<div>
			<h1>{JSON.stringify(person1)}</h1>
			<h1>{JSON.stringify(person2)}</h1>
			<h1>{JSON.stringify(person3)}</h1>
		</div>
	);
}

export default Spread;

  • Spread.js 수정
import React from 'react';

function Spread(){
	const person1 = { name : 'sooa' };
	
	const person2 = person1;
	person2.age = 20;
	
	const person3 = person2;
	person3.region = 'seoul';
	~~~~
	return (
		<div>
			<h1>{JSON.stringify(person1)}</h1>
			<h1>{JSON.stringify(person2)}</h1>
			<h1>{JSON.stringify(person3)}</h1>
		</div>
	);
}

export default Spread;

  • 객체 복사할 때 등호 연산자 쓰지 말자
  • Spread.js 수정
import React from 'react';

function Spread(){
	const person1 = { name : 'sooa' };
	const person2 = { ...person1, age : 20 };
	const person3 = { ...person2, region : 'seoul' };
	
	return (
		<div>
			<h1>{JSON.stringify(person1)}</h1>
			<h1>{JSON.stringify(person2)}</h1>
			<h1>{JSON.stringify(person3)}</h1>
		</div>
	);
}

export default Spread;

  • Spread.js 수정
import React from 'react';

function Spread(){
	const person1 = { name : 'sooa' };
	const person2 = { ...person1, age : 20 };
	const person3 = { ...person2, region : 'seoul' };
	const person4 = { ...person3, region : 'busan' };
	
	return (
		<div>
			<h1>{JSON.stringify(person1)}</h1>
			<h1>{JSON.stringify(person2)}</h1>
			<h1>{JSON.stringify(person3)}</h1>
			<h1>{JSON.stringify(person4)}</h1>
		</div>
	);
}

export default Spread;
  • Spread.js 수정
import React from 'react';

function Spread(){
	const person1 = { name : 'sooa'};
	const person2 = { ...person1, age : 20};
	const person3 = { ...person2, region : 'seoul'};
	const person4 = { region : 'busan', ...person3 };
	
	return (
		<div>
			<h1>{JSON.stringify(person1)}</h1>
			<h1>{JSON.stringify(person2)}</h1>
			<h1>{JSON.stringify(person3)}</h1>
			<h1>{JSON.stringify(person4)}</h1>
		</div>
	);
}

export default Spread;

클래스형 컴포넌트의 state

state 속성 사용하기

  • App.js
import React, { Component } from 'react';
import ClassState from './ClassState';

class App extends Component {
	render() {
		return (
			<div>
				<ClassState />
			</div>
		);
	}
}

export default App;
  • ClassState.js
import React, { Component } from 'react';

class ClassState extends Component {
		constructor(props){
		super(props);
		
		this.state = { 
			인사 : '안녕하세요'
		};
	}
		render() {
			return (
				<div>
					<h1>{this.state.인사}</h1> 
				</div>
			);
		}
}

export default ClassState;

state 값 변경하기

  • ClassState.js
// 생략
class ClassState extends Component {

	// 생략
	changeMsg = () => {
		console.log(“잘 나오나요?);
	}

	render() {
		return (
			<div>
				<h1>{this.state.인사}</h1> 
				<button onClick={this.changeMsg}>변경</button> 
			</div>
		);
	}
}
// 생략
  • ClassState.js
    • 등호 연산자 이용하면 리렌더링이 안됨
// 생략
class ClassState extends Component {
	state = { 
		인사 : '안녕하세요'
	};
	
	changeMsg = () => {
		this.setState({ 인사 : 'Hello' });
	}
	
	render() {
		return (
			<div>
				<h1>{this.state.인사}</h1> 
				<button onClick={this.changeMsg}>변경</button> 
			</div>
		);
	}
}
// 생략
💡 값 변경하는 법
  1. const [값변수, 값 변경 함수] = useState(초기값)
  2. 값 변경 ⇒ 값변수 = 변경할 값 → 값 변경 ⭕️, 화면 갱신 ❌
    값 변경 ⇒ 값 변경함수(변경할 값) → 값 변경 ⭕️, 화면 갱신 ⭕️
  3. 값 변경 원리 useState → 리액트 엔진 → 개발자가 값 변경 원함
    리액트 엔진 → 컴포넌트 방문 → JSX의 return() 확인
    → 변경 사항 체크
    → 실제 변경된 부분만 갱신
    → 변경 안 된 부분은 유지

state 끌어올리기(Lifting State Up)

형제 컴포넌트 간 데이터 공유

  • 해당 값을 필요로 하는 컴포넌트 간의 가장 가까운 공통 조상으로 state를 끌어올려 공유
  • 형제 컴포넌트에게는 직접적으로 값을 전달할 수 없음

방법

  • 상위 컴포넌트의 ‘상태를 변경하는 함수’ 그 자체를 하위 컴포넌트로 전달(props)
  • 전달된 함수를 하위 컴포넌트가 실행

새싹DT 기업연계형 프론트엔드 실무 프로젝트 과정 7주차 블로그 포스팅

0개의 댓글