[React.js]리액트의 상탯값, 속성값, 반환값
2021. 7. 8. 00:47ㆍWeb_Programming/React
리액트를 개발하면서 이론적인 내용들과 기초가 부족하다고 느껴져서 리액트 공부를 시작했습니다👍
강의는 인프런 "실전 리액트 프로그래밍"을 수강하면서 내용을 정리하는 포스팅을 작성하려 합니다.
👉 리액트 코드의 특징
일반 JS코드와 리액트를 사용한 코드를 비교해보면 아래와 같습니다.
🔹 일반 JS
<html>
<body>
<div class="todo">
/*UI 구현코드*/
<ul class="list"></ul>
<input class="desc" type="text"/>
<button onclick="onAdd()">추가</button>
</div>
<script>
let currentId=1;
const todoList=[];
function onAdd(){
const descEl = document.querySelector('.todo .desc');
const todo={ id:currentId++, desc: descEl.value}
/*생략*/
}
</script>
</body>
</html>
🔹 리액트
import React, { useState } from 'react';
export default function App(){
const [todoList, setTodoList]= useState([]);
const [desc, setDesc]= useState([]);
function onAdd(){/*생략 */}
return(
<div>
{/*UI 구현코드*/}
<ul></ul>
<input type="text" value={''} onChange={e=>{setDesc(e.target.value)}}/>
<button onClick={onAdd}>추가</button>
</div>
)
}
🚩 일반 JS VS 리액트
일반 JS [명령형] | 리액트 [선언형] |
◾데이터 변경 코드와 UI코드가 혼합 ◾ 구체적인 DOM API사용으로 DOM환경에 국한 ◾ 코드변경이 어려움. |
◾ 비지니스 로직(데이터 변경 코드)와 UI가 분리 + 데이터 변경코드는 이벤트 핸들러에서 작성 ◾ 추상화 단계가 높아 기존 비즈니스 로직에 집중할 수 있음. |
👉 컴포넌트 속성값과 상탯값
상탯값 (가변값)
: 컴포넌트 내 변경 가능한 데이터 저장소.
UI(엘리먼트)에 반영하기 위해 유지해야할 값 묶음으로 리액트 컴포넌트에 저장한 데이터가 변화하면 UI가 자동으로 리렌더링됩니다.
❗ 리액트는 일반적으로 선언한 변수가 아닌 상태값으로 선언된 값일 경우에만 변경을 인지합니다.
이를 위해 hook을 사용한 방식에서는
아래와 같이 비구조화 문법으로 useState를 사용하여 상탯값(ex. color)과 이를 변경하는 함수(ex. setColor)를 하나의 hook으로 관리합니다.
/*상탯값으로 사용*/
const [color, setColor]=useState('red');
setColor('blue'); //res -> blue변경
/*일반 변수사용*/
let color2 ='orange';
color2='green'//변경 적용 X
속성값 (불변 값)
부모(외부) 컴포넌트에서 자식(내부) 컴포넌트로 넘겨주는 데이터
+React.memo
리액트는 자식 컴포넌트의 속성값은 변화가 없어도
부모 컴포넌트의 상탯값에 변화가 있다면 해당 자식 컴포넌트가 리렌더링됩니다.
이를 방지하여 자식 컴포넌트의 속성값에 변경이 있을 때에만 리렌더링이 되도록 해주는 것이 React.memo입니다.
import React from 'react';
function Title({title}){
return <p>{title}</p>;
}
export default React.memo(Title);
속성값은 불변의 값으로,
❗ 상위 컴포넌트인 부모 컴포넌트에서만 상탯값으로서 변경이 가능하고 하위 컴포넌트에서는 변경이 불가능합니다.
+불변 변수로 관리
불변 변수로 관리하면 코드의 복잡도가 낮아지는 장점이 있어,
가변 변수인 상탯값 또한 불변 변수로 사용하는 것이 좋은데요 이를 위한 방법으로 상탯값을 객체로 관리하는 것입니다.
import React, { useState } from 'react';
export default function App(){
const [todoList, setTodoList]= useState({value:0});
const [desc, setDesc]= useState([]);
function onAdd(){
todoList.value+=1;
setTodoList(todoList);
}
return(
<div>
{/*UI 구현코드*/}
<ul></ul>
<input type="text" value={''} onChange={e=>{setDesc(e.target.value)}}/>
<button onClick={onAdd}>추가</button>
</div>
)
}
위와 같이 상탯값 todoList의 value를 직접 변경하고 이를 setTodoList로 변경을 시도하더라도 값은 변경이 안 됩니다.
그 이유는 리액트는 이전 값과 단순 비교하여 변경이 되었을 때만 변경을 적용하는데,
위는 객체의 내부 속성값만 변경한 것이지 참조값 자체가 변경된 것이 아니기 때문에 값의 변경이 적용되지 않습니다.
따라서 변경을 위해서는 전개연산자(ex. {...todoList})를 이용하여
❗ 참조값 자체를 복사하여 새로운 참조값으로 변경을 해야 합니다.
import React, { useState } from 'react';
export default function App(){
const [todoList, setTodoList]= useState({value:0});
const [desc, setDesc]= useState([]);
function onAdd(){
setTodoList({...todoList, value:todoList.value+1});
}
return(
<div>
{/*UI 구현코드*/}
<ul></ul>
<input type="text" value={''} onChange={e=>{setDesc(e.target.value)}}/>
<button onClick={onAdd}>추가</button>
</div>
)
}
👉 컴포넌트 함수의 반환값
컴포넌트 함수의 반환값으로는 여러 가지가 올 수 있습니다.
- html 태그
- 컴포넌트
- 문자열, 숫자
- 배열
❗ 배열로 반환할 때는 항상 리액트 요소가 key를 가지고 있어야 합니다.
- Fragment
여러 개의 리액트 요소를 나열할 때 key값 없이 반환 가능하도록 해줍니다.
+축약형으로 <></>로 사용 가능
import React, { useState } from "react";
export default function App() {
return (
<React.Fragment>
<p>요소</p>
<p>나열</p>
</React.Fragment>
);
}
- null, boolean (렌더링에 보이지는 않음)
- portal
index.html root 이외의 멀리 있는 곳의 요소( ex. something )에 렌더링 할 때 사용됩니다.
import React, { useState } from "react";
import ReactDOM from 'react-dom';
export default function App() {
return (
<>
<p>요소</p>
<p>나열</p>
{ReactDOM.createPortal(
<div>
<p>portal</p>
</div>
, document.getElementById("something"))}
</>
);
}
포스팅 마치겠습니다 :-D
'Web_Programming > React' 카테고리의 다른 글
[React.js]리액트 훅 규칙, Context API, 내장 훅 (0) | 2021.07.13 |
---|---|
[React.js]리액트의 가상돔, 리액트 훅 기초 (0) | 2021.07.11 |
[React]구글 Oauth2 로그인 구현 with TypeScript (0) | 2021.06.09 |
[React] 카카오 Map _지도 생성, 현 위치 재검색 구현 (+카카오 로컬 API) (4) | 2021.05.30 |
[React]리액트 다음 우편번호 검색 (4) | 2021.05.29 |