[React] 변경된 UI를 렌더하는 방법(State)

2해승·2022년 12월 19일
0

리액트는 바닐라 자바스크립트와 다르게 바뀐 UI만 업데이트해주는 큰 장점이 있다.
이를 위한 렌더방식으로 두가지 예를 들어 비교해 보자.

나쁜방법

첫번째 방식은 좋지 않은 방법으로 함수를 만들어서 계속 호출해내는 방법이다.

const root = document.getElementById("root")

let counter = 0

function countUp() {
	counter = counter + 1
	render()
    }

function render() {
	ReactDOM.render(<Container />,  root)
    }

const Container = () => (
	<div>
    	<h3>Total clicks: {counter}</h3>
        <button onClick={countUp}>Click me</button>
    </div>
    )

render()

위와같은 방식에서의 문제점은 만일 render 함수가 없었을 경우 동작 순서때문에 카운팅된 숫자가 웹페이지상에 반영되지 않게 된다.

웹페이지 상에서 반영만 안됐을뿐 콘솔에서 조회해보면 클릭 이벤트가 정상적으로 동작하고 있음을 알 수 있다.

따라서 값이 업데이트 될때마다 리렌더링을 하여 페이지에서도 업데이트 되도록 렌더링하는 코드를 함수로 만들어서 호출한다.


이처럼 매번 렌더링해주는 번거로운 방식을 벗어나서 state를 활용한 방식을 알아보자.

state를 사용하여 리액트 컴포넌트 안에서 데이터를 바꿔기전에 state에 대해 간단히 알아보자면 다음과 같다.


State?

state는 기본적으로 데이터가 저장되는 곳이다.

컴포넌트 렌더링 결과물에 영향을 주는 데이터가 저장되어 있으며 컴포넌트 안에서 데이터가 바뀌는 특징을 가지고 있다.


useState

  • 함수형 컴포넌트에 상태를 부여하는 함수
  • 상태유지값 state와 변경될때 사용하는 함수 setState로 구성되어있다.
  • state가 변경될 경우 해당 컴포넌트가 리렌더링된다.
  • React.useState()는 초기 값을 가질 수 있음 -> React.useState(0)
  const [state, setState] = React.useState(init)

  setState(newState)

useState는 [undefined, f]의 형태로 전달해 주기때문에 배열에 이름을 부여하는 방식을 사용하는게 편하다.
.
예를 들어서
const food = ['banana', 'tomato']라는 배열이 있다고 가정해보자.
배열의 값을 호출할때 아래와 같은 방식은 번거로울 수 있다.
const one = food[0]
const two = food[1]
.
이러한 번거로움을 피하기 위해 다음과 같은 방식을 사용하길 권장한다.
const [one, two] = food
one -> banana
two -> tomato

state의 Immutability(불변성)

리액트에서 state는 불변성을 유지해야한다.

state는 동적으로 변경되는 값이면서 불변성을 유지해야 한다는 특성이 의아할 수 있다.
여기서 불변성은 메모리 영역에서의 직접적인 변경이 불가능하다는 뜻이다. (재할당 가능)

기존 state의 불변성이 유지되어야 리액트 컴포넌트에서 상태 업데이트를 감지 할 수 있고 이에 따른 리렌더링이 되기 때문이다.

따라서 state의 값이 업데이트 될 때 기존 객체나 배열의 참조 주소가 변경되지 않도록 주의가 필요하다.

setState 함수의 중요도

분명하게 말하자면 setState는 값을 가진채 리렌더링을 효율적으로 해줄 수 있다.

예를 들어 setState(123123) 은 아래와 같은 기능을 한다.

counter(123123)
ReactDOM.render(<App />, root)

변경된 값을 반영하고 자동으로 리렌더링까지 한다.

useState를 활용한 방법

react.js 내에서 데이터를 보관하고 자동으로 리렌더링 하는 방식을 사용한다.

const root = document.getElementById("root")

function App() {
	const [counter, setCounter] = React.useState(0); 

	const onClick = () => {
		setCounter(counter + 1)
    }

	return (
    	<div>
        	<h3>Total clicks: {counter}</h3>
            <button onClick={onClick}>Click me</button>
        </div>
    )
}

ReactDOM.render(<App />,  root)

동작방식 : 변수를 컴포넌트에 연결하여 변수에 데이터를 담은 다음, 해당 변수에 담겨있는 값을 변경한다.

맨처음 바닐라 자바스크립트와 같은 동작을 하는 코드를 리액트로 재현할 수 있게 되었다. 아래에 코드를 삽입하여 두고두고 비교하고 기초를 까먹지 않도록 해야겠다.

-vanilla.html

<!DOCTYPE html>
<html>
    <body>
        <span>Total clicks: 0</span>
        <button id="btn">Click me</button>
    </body>
    <script>
        let counter = 0

        const button = document.getElementById("btn")
        const span = document.querySelector("span")

        function handleClick() {
            counter = counter + 1
            span.innerText = `Total clicks: ${counter}`
        }

        button.addEventListener('click', handleClick)
    </script>
</html>

변수이름붙이는 규칙!!
첫번째네임은 자기 마음대로 하고
두번째네임은 앞에 set을 붙인다
[counter, setCounterUp] 과 같은 방식으로 사용함

[참고]https://velog.io/@swimme/React-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-state-%EA%B4%80%EB%A6%AC-useState

profile
Node 백엔드 개발자 / 데브옵스 취준생

0개의 댓글