일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- angular
- TS
- 0.5px border
- 0.25px border
- TypeScript
- 데이터베이스 #try #이중
- jwt
- 10px
- 전역변수
- 0.75px border
- readonly
- entity
- 1px border
- Strict
- 컴포넌튼
- 클론코딩
- font-size
- literal
- 타입스크립트
- es6
- 서버리스 #
- ES5
- github
- 당근마켓
- npm
- &연산
- ZOOM
- Props
- 문서번호
- Websocket
- Today
- Total
복잡한뇌구조마냥
React 첫 도전기 본문
리액트를 처음 시작하는 이번주는 함께하는 다수의 분들을 한곳에 모아서 강의를 진행하는 신기한 경험을 했다.
비전공자분들이 많다보니 아무래도 진도를 따라가는 것에 어려움이 있던 것 같다.
함께 성장하는 공생관계이다보니 도울 수 있는 것은 최대한 도와드리고 나중에 다 같이 좋은 목표로 나아갔으면 한다.
기초주차에 알고리즘을 자바스크립트로 풀이하던 것에서 React를 처음 만나다보니 낯설고 어려웠다.
코드를 작성하면서 알게된 개념이나 이번 과제 풀이를 공유하고자 한다.
1. CRA (Create React App)
첫째로 리액트에 대해 알아보자.
공식 홈페이지에 적혀있는 React를 한마디로 정리하면 사용자 인터페이스를 만들기 위한 자바스크립트 라이브러리이다.
React는 컴포넌트로 웹페이지를 쪼개어 각각의 화면에 출력할 수 있는 SPA를 만들도록 도와준다.
SPA VS MPA
SPA (Single Page Application)
단일 페이지 웹 애플리케이션 최초 한 번 페이지 전체를 로드한 후 데이터만 변경하여 사용
장점 : 네이티브 앱을 쓰는 것 같은 사용자 경험 적은 서버 요청 트래픽 감소
단점 : 최초 로드 시 한번에 받아 오기 때문에 초기 구동 속도 드림 SEO(Search Engine optimization, 검색 엔진 최적화) 관점 불리
MPA (Multi Page Application)
전통적인 웹 애플리케이션 개발 방식 화면 이동 시, 화면에 필요한 HTML을 서버에서 받아서 처음부터 다시 로딩 화면 이동 시, 화면 깜빡임 (데이터가 많을 경우, 흰 화면이 계속 됨)
장점: SEO(Search Engine optimization, 검색 엔진 최적화) 관점 유리 완성된 형태의 HTML파일을 서버로 전달 받기 때문에 크롤링하기에 적합
단점 페이지 이동 시 깜빡임 현상 프론트 엔드와 백엔드의 연관이 밀접하여 개발이 복잡해질 수 있음.
리액트는 단방향 데이터 바인딩을 사용하기에 데이터 입력과 동시에 반응하지는 못한다.
데이터 바인딩이란? 뷰와 모델에 있는 데이터를 동일하게 만들어주는 것
양방향 데이터 바인딩이란 : 뷰와 모델의 데이터를 동기화 하는 것 입니다.
사용자 입력에 따라 js의 데이터가 변경되고, js의 데이터가 변경되면 사용자의 화면도 변경됩니다.
장점 : 코드의 양이 줄어든다 ( 데이터가 자동으로 변경되기 때문)
단점 : 변화에 따라 DOM객체 전체를 렌더링 하거나 데이터를 바꿔 성능이 감소되는 경우가 존재
리액트의 큰 특징은 가상DOM을 통해 웹페이지의 변화를 감지해 웹페이지의 변화된 부분만 변경을 도와준다.
또한 웹은 HTML, JAVAScript, CSS로 동작한다고 볼 수 있는데 이를 한번에 정리할 수 있다.
npx create-react-app [프로젝트명]
리액트를 설치하기 위해서는 노드.js를 설치하고 터미널에서 해당 명령어를 통해 프로젝트를 생성할 수 있다.
리액트는 npm과 yarn 으로 크게 나뉘어진 명령어를 사용하는데, 특징은 아래와 같다.
- NPM
- npm서비스를 통하여 Node.js로 개발된 프로그램을 편리하게 설치, 업데이트 및 삭제 가능
- npm 명령어를 통해 npm서비스에 등록된 Node.js로 작성된 패키지 관리
- 패키지를 설치할 때 자동으로 코드의 의존성을 실행할 수 있도록 허용, 편리하지만 안정성 위험
- YARN
- 깨져있는 npm 패키지 관리 시스템을 혁신적으로 개선
- 다운받은 패키지 데이터를 캐시에 저장, 중복된 데이터는 다운로드하지 않음(속도 상승)
- 병렬로 설치하기에 performance와 speed 증가 (npm은 순차적)
- 버전차이로 생기는 버그를 방지해줄 수 있음
라이브러리 설치로 NPM은
npm install [라이브러리]
YARN은
yarn add [라이브러리]
해당 방식을 사용한다.
npm start
yarn start
다음과 같은 명령어로 React의 프로젝트 경로로 가서 리액트를 실행할 수 있다.
2. 리액트 컴포넌트 Component
- 컴포넌트는 리액트로 만들어진 앱을 이루는 최소한의 단위라고 볼 수 있다.
- 각각의 뷰를 독립적으로 구성하여 재사용 할 수 있고, 새로운 컴포넌트를 제작하여 사용할 수 있다.
- 컴포넌트는 Props(데이터)를 받아 State(출력,상태) 에 따라 DOM Node를 출력하는 함수이다.
- 각각의 컴포넌트의 이름은 항상 대문자로 시작한다.
렌더링 ( Rendering )
컴포넌트가 현재 props와 state의 상태에 기초하여 UI를 어떻게 구성할지 컴포넌트에게 요청하는 작업을 의미한다.
State는 각각의 컴포넌트가 나타내는 상태를 나타내며, Props는 상위 컴포넌트로 부터 상속받는 데이터 값이라고 본다.
1) 클래스형 컴포넌트
- 컴포넌트 구성 요소, 리액트의 생명주기를 모두 포함하고 있다.
- 프로퍼티, state, 생명주기 함수가 필요한 구조의 컴포넌트를 만들 때 사용한다.
class App extends React.component{
constructor(props){
super(props);
}
render(){
return null;
}
//생명주기 함수
//state
}
문법은 이것과 비슷할 것 이다. 하지만 현재 리액트는 함수형 컴포넌트를 주로 사용하기때문에 넘어가려한다...
나중에 현업에 활동하게 되었을 때 남아있는 잔재를 보고 해석할 수 있는 수준정도만 알고자 한다.ㄱ
2) 함수형 컴포넌트
- 가장 간단하게 컴포넌트를 저리하는 방법은 자바스크립트 함수를 작성하는 것이다.
function App(){
return null
}
const App = () => { null }
다음과 같이 함수형으로 선언할 수 있다.
3. Hook
Hook을 이용하여 기존 Class 바탕의 코드를 작성할 필요 없이 상태 값과 여러 React의 기능을 사용할 수 있습니다.
import React, { useState } from 'react';
function Example() {
// "count"라는 새로운 상태 값을 정의합니다.
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useState는 우리가 “Hook”에서 처음 배우게 될 함수입니다. 데이터의 상태값을 나타내고, 수정하는 Hook이라고 생각하자.
해당 코드는 import를 통해 react라이브러리에서 useState 훅을 불러오고,
count라는 변수에 0이라는 초기 값을 주고, setCount라는 함수로 count의 상태 값을 변경하는 내용이다.
간단하게 React에 대해 알아보았으니 이번 과제를 뜯어보도록 하자.
- React로 TodoList만들기 -
GOAL : My Todo List 만들기
구현해야할 기능
- UI구현하기
- Todo 추가 하기
- Todo 삭제 하기
- Todo 완료 상태 변경하기 ( 완료 ↔ 진행중)
과제 요구 사항
- 제목과 내용을 입력하고, [추가하기] 버튼을 클릭하면 Working에 새로운 Todo가 추가되고 제목 input과 내용 input은 다시 빈 값으로 바뀌도록 구성해주세요.
- Todo의 isDone 상태가 true이면 취소 false이면 완료 라벨을 조건부로 렌더링 해주세요.
- Todo의 상태가 Working이면 위쪽, Done이면 아래쪽에 위치하도록 구현합니다.
- Layout의 최대 넓이는 1200px, 최소 넓이는 800px로 제한하고, 가운데로 정렬해주세요.
- 폴더 구조는 아래와 동일하게 구현하고, 컴포넌트 구성도 똑같이 나눠서 구현해주세요.
GitHub에 과제에 대한 Readme 파일을 작성하였습니다. 해당 과제는 다음과 같이 TodoList를 제작하는 것입니다.
젤 위에 사진은 숙련주차 과제를 끝내고 개조해서 테스트하는 중이라 입문과제와 약간의 차이가 있을 수 있습니다.
1. TodoList.jsx
import React, {useState} from "react";
import Layout from "../components/layout/Layout"
function TodoList(){
const [todos, setTodos] = useState([
{
id: 1,
title: "리액트 공부하기",
desc: "리액트 기초를 공부해봅시다.",
isDone: false
},
{
id: 2,
title: "리액트 공부하기",
desc: "리액트 기초를 공부해봅시다.",
isDone: true
},
]);
const onRemove = (id) => {
setTodos(todos.filter(todo => todo.id !== id));
};
const onChange = (id) => {
setTodos(todos.map(
todo => todo.id === id
? { ...todo, isDone: !todo.isDone }
: todo
))
}
const addTodo = (title, desc) =>{
const todo ={
id: todos.length+1,
title:title,
desc:desc,
isDone:false
}
setTodos([...todos, todo]);
}
return (
<>
<Layout todos = {todos} onChange={onChange} onRemove={onRemove} addTodo={addTodo}/>
</>
)
}
해당 코드는 Pages의 TodoList의 코드입니다.
각각의 Todo의 데이터값을 페이지에서 저장하고 , Todo값의 변화를 주는 기능 함수들을 페이지에서 할당시켜줬습니다.
1) todos는 각각의 todo값을 가지는 오브젝트 값이며, setTodos를 이용하여 데이터를 변경할 수 있습니다.
2) addTodo는 제목과 내용을 입력받아 새로운 todo값을 얻어 todos에 추가하는 함수 입니다.
... 문법을 통해 todos의 각각의 데이터값을 모두 가져와 새로운 todo를 추가로 넣습니다.
해당 풀이에는 함정이 있습니다.
id값이 todos 오브젝트의 크기로 되어 있는데, 이렇게 하면 삭제하기에 중복이 생기게 됩니다.
당시에 다수의 캠프 참가자분들께 코드를 공유하는 상황이라 풀이를 너무 따라가실까봐
풀이를 수정하지않았습니다. (각자에게 주는 문제같은 느낌으로 남겨둠)
저는 1주차 미니프로젝트 때 문서번호 작성에 동일한 질문을 풀어본 경험이 있습니다.
전역 변수를 선언하여, 추가할 때마다 전역변수에 값을 변경하도록 지정해주면 편하게 관리가능합니다.
3) onRemove는 filter함수를 통해 해당 삭제하기를 당한 id값을 제외한 todo값만 남겨놓습니다.
4) onChange는 id값이 일치하는 todo를 찾아 해당 isDone 변수만 변경하고 나머지는 유지하는 함수입니다.
5) 데이터는 남겨두고 Layout에 props로 todos값과 추가,수정,삭제를 보내 CRUD가 가능하도록 넘겨줍니다.
모든 기능과 데이터를 한 곳에 모아서 관리에 용이점을 주는 것에 초점을 두었습니다.
2. Layout.jsx
import React from "react";
import './style.css'
import Header from "../header/Header";
import Form from "../form/Form";
import List from "../list/List";
function Layout({todos, onChange, onRemove, addTodo}){
return(
<div className="layout">
<Header/>
<Form addTodo={addTodo}/>
<List todos = {todos} onChange={onChange} onRemove={onRemove}/>
</div>
)
}
export default Layout;
1) import를 통한 각각의 컴포넌트 호출
2) 각각의 컴포넌트를 위에서부터 순서대로 출력되도록 순서에 맞게 호출
3) TodoList로 받은 props값을 기능에 맞춰 각각의 컴포넌트로 상속
4) export로 외부에서 사용가능하도록 정의
이후 코드에서는 필요 기능만 코드를 잘라서 표기하겠습니다.
3. Form.jsx
<label>
제목
<input className='input' type="text" value={title}
onChange={(event) => {
setTitle(event.target.value);
}} />
</label>
<button
className='int_btn'
onClick={() => {
if(title !== "" && desc !== ""){
addTodo(title, desc);
setTitle("");
setDesc("");
}}}>
추가하기
</button>
1) input을 통한 value값 선정 (해당 값으로 변경)
2)onChange를 통한 값 변경 setTitle로 useState Hook을 사용하여 input작성 값을 할당하여 변경
3) 제목 title, 내용 desc를 addTodo함수로 보내줌으로서 생성함수 사용
4) 빈칸의 input은 입력 제한, 추가 후 내용 공백으로 변경
4. List.jsx
<h1>Working..🔥</h1>
<div className="work-container">
{todos.map(todo =>
todo.isDone === false
?<Todo todo={todo} onChange={onChange} onRemove={onRemove} key={todo.id}/>
:null
)}
</div>
1) map을 통해 todos의 각각의 값을 받아 isDone이 false인 값들만 출력하도록 선정
2)삼항 연산자를 사용하여 Todo.jsx에 데이터값을 보내주는것과 해당하지않으면 null출력하도록 선정
※자바스크립트 반복문 : map 함수, 조건문: 삼항연산자
5. Todo.jsx
<>
<div className="todo" key={todo.id}>
<h1>{todo.title}</h1>
<p>{todo.desc}</p>
<div className='btn_set'>
<button className='del_btn' onClick={()=> onRemove(todo.id)}>
삭제하기
</button>
{ todo.isDone === false
?<button className='opt_btn' onClick={()=> onChange(todo.id)}>완료</button>
:<button className='opt_btn' onClick={()=> onChange(todo.id)}>취소</button>
}
</div>
</div>
</>
1) 하나의 묶음으로 전달되지않으면 return에 오류 발생하므로 <>공백의 태그로 묶어줌(DOM요소)
2) 받아온 데이터의 각각의 값을 이용하여 출력
3) 함수에 id값을 전달하여 작동하도록 사용
기능적으로 구현에 대해 간단히 설명해봤습니다.
입문주차답게 적절한 난이도로 기본적인 기능을 찾아보면서 즐겁게 풀이를 했던 것 같습니다.
자료 출처:
React: https://ko.reactjs.org/
Props, State : https://studyingych.tistory.com/52
리액트 입문 과제 : https://github.com/Yoepee/React_week1.git
'이노베이션 캠프 > 회고록' 카테고리의 다른 글
리액트 키워드 정리 (리덕스, 미들웨어, 프로미스, axios 등) (0) | 2022.08.29 |
---|---|
RRR( React, Redux, Route ) (0) | 2022.08.25 |
2주차 프로그래밍 기초 협업 내용 정리 (0) | 2022.08.15 |
알고리즘 테스트를 마치며... (0) | 2022.08.14 |
알고리즘 진행 과정 중간 결산 (0) | 2022.08.10 |