리액트 기초과정 CS
1. 리액트의 기본 개념과 원리 중 "가상 돔(Virtual DOM)"에 대해 설명해주세요.
가상 돔(Virtual DOM)은 실제 DOM에 접근하여 조작하는 대신, 이것을 추상화시킨 자바스크립트 객체를 이용해 사용하는 것으로, 실제 (무거운) DOM의 가벼운 사본 같은 개념
[리액트가 가상돔을 반영하는 절차]
- 변화가 일어나면 변화된 버전을 가상돔으로 바꾼다
데이터가 업데이트되면 전체 UI를 가상돔에 리렌더링 - 가상돔끼리 비교
변화 전의 가상돔과 변화된 가상돔을 비교함 - 바뀐 부분만 적용
바뀐 부분만 실제 돔에 적용을 함으로써 레이아웃 계산은 일괄로 단 한 번만 이행
작은 규모의 레이아웃(리플로우)이 여러번 발생하는 것보다 큰 규모의 레이아웃이 한 번 발생하는 것은 성능상의 큰 차이
=> 리액트는 이와 같은 얕은 비교와 일괄 돔 업데이트 방식을 이용해 성능 향상을 이끌어냄
2. 리액트에서 자주 사용되는 자바스크립트 필수 문법 중 "비구조화 할당(Destructuring Assignment)"에 대해 설명해주세요.
배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 해주는 자바스크립트 표현.
배열, 객체 내 값을 추출하는 코드가 매우 간단해지며,
필요한 객체와 나머지 요소 분리(...전개연산자 이용)가 매우 간단하다.
또한, 기본값 지정이 가능하다.
[배열 구조분해할당]
할당문의 좌변에서 사용하여, 우변의 어떤 값을 분해해 할당할지 정의함.
index에 따라 값이 할당
[객체 구조분해할당]
동일한 key값에 할당
=> 리액트에서는 주로 useState와 props로 받아온 값들을 비구조화 할당으로 꺼내서 사용.
3. CRA(Create React App)를 사용하여 개발 환경을 구축하는 방법에 대해 설명해주세요.
- 원하는 위치의 폴더에 쉬프트+우클릭하여 파워쉘에서 터미널 열기
|| 터미널에서 폴더 구조를 찾아들어갈 경우
- 시작프로그램에서 터미널 검색해서 power shell 켜거나 git bash사용해도 무방
- ls #현재 내가 어디 위치하고 있는 폴더가 어디인지 확인할 수 있음
- cd 폴더이름 #리액트 프로젝트를 생성하고 싶은 폴더로 들어감 - [터미널] yarn create react-app 폴더명
- 입력한 폴더명으로 하위에 프로젝트가 생성됨.
src 폴더가 주로 작업할 공간이며, 그 중 특히 App.js - 상대경로 import를 절대경로로 지정하기
jsconfig.json 파일을 root 경로에 만들어준다.
다음 내용 작성해주면 됨
{ "compilerOptions": { "baseUrl": "src" }, "include": ["src"] }
4. ‘부모 컴포넌트’와 ‘자식 컴포넌트’ 사이에서 데이터를 전달하는 방식에 대해 설명해주세요.
컴포넌트 간의 정보를 교류할 때 props를 사용한다.
props는 반드시 위에서 아래방향으로 흐르는 단방향.
반드시 읽기 전용으로 취급하며 변경하지 않는다.
사용자 정의 컴포넌트로 작성한 엘리먼트에서 props에서 사용할 이름=값 형태로 속성을 부여하면,
해당 컴포넌트의 인자에서 props의 값을 받을 수 있다.
props는 부모 컴포넌트가 자식에게 넘겨준 데이터들의 묶음.
props가 부모에서 자식으로, 또 자식에서 그 자식으로
반복하여 내려줄 수 있는데 이를 prop driling이라 함.
이와 같은 패턴을 피하기 위해 Redux와 같은 데이터 상태관리 툴을 사용함
5. JSX 문법이 무엇이지, 일반 HTML 문법과는 어떤 차이가 있는지 설명해주세요.
JSX는 JavaScript와 XML을 합친 것으로 Javascript를 확장한 문법.
JavaScript의 모든 기능이 포함되어 있으며, 리액트 엘리먼트를 생성하기 위한 문법이다.
컴포넌트 안에서 return()이 JSX를 작성하는 공간
- 모든 태그는 닫아줘야 함 <input />
- 무조건 1개의 엘리먼트를 반환
- {}중괄호를 이용해 JSX 안에서 JavaScript의 값, map, 삼항연산자 등의 문법을 사용할 수 있다.
- class대신 className
- 인라인으로 style줄 땐 json객체 형식. <p style={{fontSize: '20px', color: 'orange'}}></p>
6. 리액트에서 ‘Props’와 ‘State’의 역할과 차이점에 대해 설명해주세요.
props는 부모 컴포넌트에서 물려받은 읽기전용 값으로 변경하지 않는다.
state는 컴포넌트 내부에서 바뀔 수 있는 값. UI를 바꾸기 위한 목적(리렌더링)으로 사용
따라서, 값이 바뀌어야 하는 정보는 state로 작성한다.
7. 불변성(Immutability)의 원칙과 순수 함수의 개념 및 역할에 대해 설명해주세요.
[불변성]
불변성은 메모리에 있는 값을 변경할 수 없는 것을 말한다.
자바스크립트의 데이터 형태 중 원시 데이터는 (값을 변경하려면, 공간을 새로 만들어서 새로운 값의 메모리 주소를 바라보게 하기 때문에) 불변성이 있으며,
원시 데이터가 아닌 객체, 배열, 함수는 (기본적으로 메모리에서 주소 값을 바라보고 있기 때문에 값을 바꿔도 메모리 주소는 같고, 안의 값이 바뀌는 셈이므로) 불변성이 없다.
즉, 메모리 주소가 바뀌었는 지를 비교하여 불변성을 판단.
리액트는 화면의 리렌더링 기준이 state인데
state에서 원시데이터가 아닌 데이터를 수정 시, 메모리 주소는 변함이 없기 때문에
불변성을 지켜주지 않아서 리렌더링이 일어나지 않음. [...전개연산자] {...전개연산자}를 이용하여 state에서 불변성을 지켜줄 수 있음
[순수함수]
순수함수는 하나 이상의 인자를 받고, 인자를 변경하지 않고, 참조하여 새로운 값을 반환하는 함수이다.
즉, 같은 input(동일한 인자)가 전달되면 항상 동일한 결과를 반환해야 하는 함수
함수의 안팎에서 뭔가 예기치 않은 일이 생길 가능성이 있는 함수는 순수함수가 될 수 없다.
- http요청을 보내는 함수, 데이터 저장, 쿠키 조작 -> 순수함수 될 수 없음X
비동기 요청을 보내는 함수는 요청이 실패할 가능성이 있다. - 입력을 내포한 함수 -> 순수함수 될 수 없음X
입력을 포함하는 함수도 입력에 따라 출력이 달라질 가능성이 있기 때문에 순수함수가 될 수 없다. - 파라미터를 직접 변경하는 함수 -> 순수함수 될 수 없음X
매개변수로 들어온 값을 직접 변경하는 함수 역시 순수함수가 될 수 없다.
배열과 같은 참조 자료형 객체를 어떤 함수 안에서 직접 변경한다면,
나중에 이 객체를 인자로 받는 다른 함수의 작업에 영향을 미칠 수 있기 때문이다.
컴포넌트의 상태값(state)은 불변 객체로 관리해야 함. 직접 조작을 피하는 방식으로 부수 효과를 방지.
수정할 때에는 기존 값을 변경하는 것이 아니라, 같은 이름의 새로운 객체를 생성합니다.
new스테이트 = [...스테이트];
+ state, props가 변경될 때 리렌더링이 되기 때문에
의도치 않게 부수효과를 가진 함수들로 인해 불필요한 리렌더링이 잦아질 수 있음!
8. 반복되는 컴포넌트를 처리하고 분리하는 방법에 대해 설명해주세요.
[반복되는 컴포넌트 처리]
JSX 부분에서 자바스크립트 map을 사용하여 반복되는 컴포넌트를 처리할 수 있다.
return (
...
{state이름.map((item)=>{
return(
// 여기에 반복되는 컴포넌트 작성
)
})}
)
[컴포넌트로 분리]
// 컴포넌트로 분리해서 구현 - return()문 밖 JavaScript 사용하는 영역에서 만들기
function Component이름(props) {
return ({/* JSX작성 */})
}
// 사용 - JSX영역에서 사용
<Component이름 />
9. 독립 컴포넌트를 작성하고 타 프로젝트에서 재사용하는 방법에 대해 설명해주세요.
여러번 렌더링하거나, 기능을 재사용하는 컴포넌트들은 따로 분리
- 컴포넌트 분리를 통해 각 컴포넌트의 역할을 명확히 해줌
App.js는 조립만 하도록 하여 역할을 명확히 함 - 연관된 컴포넌트끼리 폴더를 만들어 관리하여 컴포넌트 개수가 많아져도 찾기 수월하도록 함
// 별도 파일에서 컴포넌트 생성 후 export
function Component이름(props) {
return ({/* JSX작성 */})
}
export default Component이름;
// 사용할 파일에서 import 해주고, 컴포넌트로 작성한 엘리먼트 JSX에서 사용
import {Component이름} from "파일경로"
...
<Component이름 />