[React] 리액트 상태값, 속성값, 반환값

cool_kim·2021년 7월 7일
0

React

목록 보기
2/8
post-thumbnail

무작위로 필요한 문제만 검색해서 개발했던 리액트였기 때문에 기본기를 다지고자 개념부터 차근차근 정리하면서 공부하는 포스팅입니다😄

같은 동작을 하는 코드를 HTML과 js로 짰을 때와 리액트로 짰을 때를 비교해 봅시다.

  • HTML + js
<html>
	<body>
    	<div class ="todo">
        	<h3>할 일 목록</h3>
            <ul class="list></ul>
            <input class="desc" type="text" />
            <button onclick="onAdd()">추가</button>
            <button onclick="onSaveToServer()">서버에 저장</button>
        </div>
        <script>
	        let currentId = 1;
            const todoList = [];
            function onAdd() {
            	const descEl = document.querySelector('.todo .desc');
                const todo = { id : currentId++, desc: descEl.value };
                todoList.push(todo);
                const listEl = document.querySelector('.todo .list');
                const todoEl = makeTodoElement(todo);
                list.appendChild(todoEl);
            }
            /* 생략 */
        </script>
     </body>
 </html>  
  • React.js
import React, { useState } from 'react';

export default function App() {
	const [todoList, setTodoList] = useState([]);
    const [currentId, setCurrentId] = useState(1);
    const [desc, setDesc] = useState('');
    function onAdd() {
    	const todo = { id: currentId, desc };
        setCurrentId(currentId + 1);
        setTodoList([...todoList, todo]);
    }
    function onDelete(e) {
    	const id = Number(e.target.dataset.id);
        const newTodoList = todoList.filter(todo => todo.id !== id);
        setTodoList(newTodoList);
    }
    function onSaveToServer() {}
    return (
    	<div>
        	<h3>할 일 목록</h3>
            <ul>
            	{todoList.map(todo => {
                	<li key={todo.id}>
                    	<span>{todo.id}</span>
                        <button data-id = {todo.id} onClick={onDelete}>
                        	삭제
                        </button>
                    </li>
                ))}
            </ul>
            <input type="text" value={desc} onChange={e => setDesc(e.target.value)} />
            <button onClick={onAdd}>추가</button>
            <button onClick={onSaveToServer}>서버에 저장</button>
        </div>
    );
}

html은 명령형 프로그래밍 -> dom api 사용해야 요소 접근 할 수 있음
리액트는 선언형 프로그래밍 -> 가상 돔 사용



useState

  • 컴포넌트에 상태값을 추가할 수 있음
  • 매개변수는 상태값의 초기값을 의미
  • 배열을 반환
    const [todoList, setTodoList] = useState([]);
    => 배열 비구조화 문법



리액트의 속성값 그리고 상태값

  1. 상태값으로 관리
    : 불변 변수 아님, 하지만 불변 변수로 관리 하는 것이 좋음
    - 불변 변수로 관리하면 코드의 복잡도가 낮아짐
    ** 전개 연산자를 사용하여 불변변수로 사용할 수 있음
    setCount({ ...count, value: count.value + 1 });
const [color, setColor] = useState("red");
function onClick() {
	setColor('blue");
}
return (
	<button style={{ backgroundColor: color }} onclick = {onClick}>좋아요</button>
);

: 컴포넌트 내에 변경 가능한 데이터 저장소로 가변값임
: 같은 컴포넌트가 여러개 쓰이더라도 상태값을 위한 자신만의 메모리가 있어 각자의 상태값을 유지함

  1. 속성값으로 관리
    : 불변변수 (값을 변경하려 하면 에러 발생)

Title.js

export default function Title({ tite }) {
	return <p>{title}</p>
}

Counter.js

export default function Counter() {
	const [count, setCount] = useState(0);
	function onClick() {
		setCount(count + 1);
	}
	return (
		<div>
		<Title title={`현재 카운트 : ${count}` />
		<button onClick={onClick}>증가</button>
		</div>
	);
}

카운터 컴포넌트에서 타이틀 컴포넌트를 사용,
부모컴포넌트가 렌더링 될 때마다 자식 컴포넌트가 같이 렌더링 됨.

React.memo

: 속성값이 변경 될 때만 컴포넌트가 렌더링 되게 하기 위한 라이브러리
: 자식 컴포넌트의 속성값에 변경이 있을 경우에만 렌더링 됨

Title.js

function Title({ tite }) {
	return <p>{title}</p>
}
export default React.memo(Title);

같은 컴포넌트가 여러개 쓰이더라도 상태값을 위한 자신만의 메모리가 있어 각자의 상태값을 유지함


📍 리액트는 상태값 변경 유무를 이전값과의 단순 비교로 하는데 객체의 참조값은 변하지 않고 단순히 내부의 속성값만 변경이 된 상태라면 리액트 입장에서는 값이 변경되지 않았다고 판단함. 아래 코드는 화면이 변하지 않음

export default function Counter() {
	const [count, setCount] = useState({ value : 0 });
	function onClick() {
		count.value += 1; //여기서 값 직접 수정
		setCount(count);
	}
	return (
		<div>
			<Title title={`현재 카운트 : ${count}` />
			<button onClick={onClick}>증가</button>
		</div>
	);
}



반환값

리액트는 컴포넌트 함수의 반환값으로 다음과 같은 값을 반환 할 수 있다.

  • html 요소
  • 문자열
  • 컴포넌트
  • 숫자
  • 배열
    - 리액트 요소가 key를 가지고 있어야 함 (가상돔에서 연산을 효율적으로 할 수 있음)
  • 리액트 portal
    - html에서 root엘리먼트 말고 다른 멀리 떨어진 엘리먼트에 렌더링 하고 싶을 때 사용(모달 코딩을 위해 많이 사용됨)

Fragment

: <></>태그
✔ 키를 입력하지 않아도 에러가 나지 않음
✔ 여러개의 요소를 반환할 때 유용하게 사용됨
✔ 실제 돔에는 반영되지 않고 에러 나지 않고 반환할 수 있음
✔ {null}, {false} 조건부 출력 때 유용하게 사용

조건부 렌더링

{ count.value === 0 && <Title title={현재 카운트: ${count.value} />}

profile
FE developer

0개의 댓글