본문 바로가기

WINK-(Web & App)/React.js 스터디

[2024-2 React.js 스터디] 김지수 #1주차

반응형

리액트는 어쩌다 만들어졌을까?

리액트는 어떠한 상태가 바뀌었을때, 그 상태에 따라 DOM 을 어떻게 업데이트 할 지 규칙을 정하는 것이 아니라, 아예 다 날려버리고 처음부터 모든걸 새로 만들어서 보여준다면 어떨까? 라는 아이디어에서 개발이 시작되었습니다. 리액트는 상태가 업데이트 되면, 업데이트가 필요한 곳의 UI 를 Virtual DOM 을 통해서 렌더링합니다. 그리고 나서 리액트 개발팀이 만든 매우 효율적인 비교 알고리즘을 통하여 실제 브라우저에 보여지고 있는 DOM 과 비교를 한 후, 차이가 있는 곳을 감지하여 이를 실제 DOM 에 패치시켜줍니다. 이를 통하여, "업데이트를 어떻게 할 지" 에 대한 고민을 하지 않으면서, 빠른 성능도 지켜낼 수 있게 되었습니다.


리액트 컴포넌트

App.js

import React from 'react';
function Hello() {
return <div>안녕하세요</div>
}
export default Hello;

리액트 컴포넌트를 만들 땐

import React from 'react';

를 통하여 리액트를 불러와주어야 합니다.

export default Hello;

이 코드는 Hello 라는 컴포넌트를 내보내겠다는 의미입니다. 이렇게 해주면 다른 컴포넌트에서 불러와서 사용 할 수 있습니다.

 

Hello.js

import React from 'react';
import Hello from './Hello';
function App() {
return (
<div>
<Hello />
</div>
);
}

export default App;

상단에 있던

import logo from './logo.svg';
import './App.css';

는 SVG 파일을 불러오고, CSS 를 적용하는 코드인데 이는 현재 불필요하므로 제거해주었습니다.


JSX의 기본 규칙

 

꼭 닫혀야 하는 태그

태그는 꼭 닫혀있어야 합니다. 

다음과 같은 코드는 오류가 발생하게 됩니다.

 

꼭 감싸져야하는 태그

두가 이상의 태그는 무조건 하나의 태그로 감싸져있어야 합니다. 한번 다음 코드를 작성해보세요.

 

JSX 안에 자바스크립트 값 사용하기

JSX 내부에 자바스크립트 변수를 보여줘야 할 때에는 {} 으로 감싸서 보여줍니다.

 

style 과 className

JSX 에서 태그에 style 과 CSS class 를 설정하는 방법은 HTML 에서 설정하는 방법과 다릅니다.

우선, 인라인 스타일은 객체 형태로 작성을 해야 하며, background-color 처럼 - 로 구분되어 있는 이름들은 backgroundColor 처럼 camelCase 형태로 네이밍 해주어야 합니다.

 

주석

이제, JSX 에서 주석은 어떻게 작성하는지 알아봅시다.

JSX 내부의 주석은 {/* 이런 형태로 */} 작성합니다.


props 를 통해 컴포넌트에게 값 전달하기

 

props 의 기본 사용법

예를 들어서, App 컴포넌트에서 Hello 컴포넌트를 사용 할 때 name 이라는 값을 전달해주고 싶다고 가정해봅시다. 그러면, 이렇게 코드를 작성하면 됩니다.

 

여러개의 props, 비구조화 할당

props 내부의 값을 조회 할 때마다 props. 를 입력하고 있는데요, 함수의 파라미터에서 비구조화 할당 (혹은 구조 분해라고도 불립니다) 문법을 사용하면 조금 더 코드를 간결하게 작성 할 수 있습니다.

 

defaultProps 로 기본값 설정

컴포넌트에 props 를 지정하지 않았을 때 기본적으로 사용 할 값을 설정하고 싶다면 컴포넌트에 defaultProps 라는 값을 설정하면 됩니다.


조건부 렌더링

조건부 렌더링이란, 특정 조건에 따라 다른 결과물을 렌더링 하는 것을 의미합니다.

 

props 값 설정을 생략하면 ={true}

컴포넌트의 props 값을 설정하게 될 때 만약 props 이름만 작성하고 값 설정을 생략한다면, 이를 true 로 설정한 것으로 간주합니다.

 

import React from 'react';
import Hello from './Hello';
import Wrapper from './Wrapper';

function App() {
return (
<Wrapper>
<Hello name="react" color="red" isSpecial />
<Hello color="pink"/>
</Wrapper>
);
}

export default App;

이렇게 isSpecial 이름만 넣어주면 isSpecial={true} 와 동일한 의미입니다.


useState 를 통해 컴포넌트에서 바뀌는 값 관리하기

리액트 16.8 이전 버전에서는 함수형 컴포넌트에서는 상태를 관리할 수 없었는데요, 리액트 16.8 에서 Hooks 라는 기능이 도입되면서 함수형 컴포넌트에서도 상태를 관리할 수 있게 되었습니다. 이번에는 useState 라는 함수를 사용해보게 되는데, 이게 바로 리액트의 Hooks 중 하나입니다.

 

이벤트 설정

import React from 'react';
function Counter() {
const onIncrease = () => {
console.log('+1')
}
const onDecrease = () => {
console.log('-1');
}
return (
<div>
<h1>0</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
);
}

export default Counter;

함수를 만들고, button 의 onClick 으로 각 함수를 연결해주었습니다. 리액트에서 엘리먼트에 이벤트를 설정해줄때에는 on이벤트이름={실행하고싶은함수} 형태로 설정해주어야 합니다.

 

여기서 주의하셔야 하는 점은, 함수형태를 넣어주어야 하지, 함수를 다음과 같이 실행하시면 안됩니다.

onClick={onIncrease()}

이렇게 하면 렌더링되는 시점에서 함수가 호출되버리기 때문입니다. 이벤트를 설정할때에는 함수타입의 값을 넣어주어야 한다는 것, 주의해주세요.

 

동적인 값 끼얹기, useState

컴포넌트에서 동적인 값을 상태(state)라고 부릅니다. 리액트에 useState 라는 함수가 있는데요, 이것을 사용하면 컴포넌트에서 상태를 관리 할 수 있습니다.

 

함수형 업데이트

지금은 Setter 함수를 사용 할 때, 업데이트 하고 싶은 새로운 값을 파라미터로 넣어주고 있는데요, 그 대신에 기존 값을 어떻게 업데이트 할 지에 대한 함수를 등록하는 방식으로도 값을 업데이트 할 수 있습니다.


배열 렌더링하기

배열이 고정적이라면 상관없겟지만, 배열의 인덱스를 하나하나 조회해가면서 렌더링하는 방법은 동적인 배열을 렌더링하지 못합니다.

동적인 배열을 렌더링해야 할 때에는 자바스크립트 배열의 내장함수 map() 을 사용합니다. 

map() 함수는 배열안에 있는 각 원소를 변환하여 새로운 배열을 만들어줍니다. 리액트에서 동적인 배열을 렌더링해야 할 때는 이 함수를 사용하여 일반 데이터 배열을 리액트 엘리먼트로 이루어진 배열로 변환해주면 됩니다.


배열에 항목 추가하기, 제거하기, 수정하기

 

배열에 항목 추가하기

1.우선, input 두개와 button 하나로 이루어진 CreateUser.js 라는 컴포넌트를 src 디렉터리에 만들어봅시다.

 

2.이번 컴포넌트에서는 상태관리를 CreateUser 에서 하지 않고 부모 컴포넌트인 App 에서 하게 하고, input 의 값 및 이벤트로 등록할 함

수들을 props 로 넘겨받아서 사용해주겠습니다.

 

3.이 컴포넌트를 App 에서 UserList 위에 렌더링해보세요.

 

4.CreateUser 컴포넌트에게 필요한 props 를 App 에서 준비해주겠습니다.

 

5.코드를 작성 후, input 에 값을 입력하고, 등록 버튼을 눌렀을 때 input 값들이 잘 초기화되는지 확인해보세요.

그 다음에는, users 도 useState 를 사용하여 컴포넌트의 상태로서 관리해주세요.

 

6.이제 배열에 변화를 줄 차례입니다. 배열에 변화를 줄 때에는 객체와 마찬가지로, 불변성을 지켜주어야 합니다. 그렇기 때문에, 배열의 push, splice, sort 등의 함수를 사용하면 안됩니다. 만약에 사용해야 한다면, 기존의 배열을 한번 복사하고 나서 사용해야합니다.

 

배열에 항목 제거하기

1.UserList 에서 각 User 컴포넌트를 보여줄 때, 삭제 버튼을 렌더링해주세요.

 

2.User 컴포넌트의 삭제 버튼이 클릭 될 때는 user.id 값을 앞으로 props 로 받아올 onRemove 함수의 파라미터로 넣어서 호출해주어야 합니다.

여기서 onRemove "id 가 __인 객체를 삭제해라" 라는 역할을 가지고 있습니다.

이 onRemove 함수는 UserList 에서도 전달 받을것이며, 이를 그대로 User 컴포넌트에게 전달해줄것입니다.

이제, onRemove 함수를 구현해봅시다. 배열에 있는 항목을 제거할 때에는, 추가할떄와 마찬가지로 불변성을 지켜가면서 업데이트를 해주어야 합니다.

불변성을 지키면서 특정 원소를 배열에서 제거하기 위해서는 filter 배열 내장 함수를 사용하는것이 가장 편합니다. 이 함수는 배열에서 특정 조건이 만족하는 원소들만 추출하여 새로운 배열을 만들어줍니다.

App 컴포넌트에서 onRemove 를 다음과 같이 구현후, UserList 에게 전달해주세요.

 

3.이제 버튼들을 눌러서 삭제가 잘 이루어지는지 확인해보세요.

배열에 항목 수정하기

1.우선, App 컴포넌트의 users 배열 안의 객체 안에 active 라는 속성을 추가해주세요.

 

2.그 다음에는 User 컴포넌트에서 방금 넣어준 active 값에 따라 폰트의 색상을 바꿔주도록 구현을 해보세요. 추가적으로, cursor 필드를

설정하여 마우스를 올렸을때 커서가 손가락 모양으로 변하도록 하겠습니다.

 

3.이제 App.js 에서 onToggle 이라는 함수를 구현해보겠습니다. 배열의 불변성을 유지하면서 배열을 업데이트 할 때에도 map 함수를 사용 할 수 있습니다.

 

4.id 값을 비교해서 id 가 다르다면 그대로 두고, 같다면 active 값을 반전시키도록 구현을 하시면 됩니다.

 

5.onToggle 함수를 만들어서 UserList 컴포넌트에게 전달해주세요.

 

6.그 다음에는 UserList 컴포넌트에서 onToggle를 받아와서 User 에게 전달해주고, onRemove 를 구현했었던것처럼 onToggle  id 를 넣어서 호출해주세요.

 

7.다른 계정명을 눌러서 초록색으로 되는지, 그리고 또 다시 눌렀을때 검정색으로 변하는지, 확인해보세요.

반응형