
React – 기초
프론트엔드 개발을 위한 JavaScript 오픈소스 라이브러리
→ 웹, 데스크탑, 모바일 등 다양한 플랫폼에서 활용 가능
→ 컴포넌트 단위로 나눠서 개발함
React의 3가지 특징
- 선언형
- 컴포넌트 기반
- 범용성
선언형(Declarative)(명시적)
코드를 자세히 분석하지 않고도 코드의 의도를 분명히 알 수 있게 하는 것(직관적)
→ 리액트는 한 페이지를 보여주기 위해 html/css/js로 나눠서 적기보다는
하나의 파일에 명시적으로 작성할 수 있게 jsx를 활용한 선언형 프로그래밍을 지향!
컴포넌트 기반(Component-Based)
리액트는 하나의 기능 구현을 위해 여러 종류의 코드를 묶어둔 컴포넌트를 기반으로 함
→ 컴포넌트로 분리하면 상호 독립적/재사용 가능
→ 기능 자체에 집중한 개발 가능, 유지보수, 유닛 테스트에도 유용
범용성(Learn Once, Write Anywhere)
리액트는 JavaScript 오픈소스 라이브러리
→ JavaScript 프로젝트 어디에든 유연한 적용 가능
→ Facebook에서 관리되어 안정적이고 가장 유명하며, 리액트 네이티브(리액트의 형제격)로 모바일 개발도 가능
cf.) 앵귤러(angular)의 경우 프레임워크가 생태계에 종속되어 있음
React Intro
학습 목표
* React의 3가지 특징
* JSX에 대한 이해(why 명시적)와 작성법
* React 컴포넌트(React Component)의 필요성
JSX
JSX(JavaScript XML)란 JavaScript를 확장한 문법
→ React에서 UI를 구성할 때 사용하는 문법(jsx: 문자열x, html x)
JSX는 브라우저가 바로 실행할 수 없다
→ 컴파일 작업이 필요
Babel
JSX를 브라우저가 이해할 수 있는 JavaScript로 컴파일 해주는 컴파일러
DOM과 React JSX
DOM: html, css, js(javascript)
React DOM: css, jsx
→ React 에서는 DOM과 다르게 CSS, JSX 문법만으로 웹 어플 개발 가능
→ JSX를 사용해서 JavaScript만으로 마크업 형태(html 의 언어인)의 코드를 작성하여 DOM에 배치 가능
주의점 : JSX는 HTML이 아니다 (생김새는 비슷해도)
JSX를 쓰는 이유?
한 눈에 볼 수 있는 기능과 디자인: JavaScript와 html 문법을 한 뭉치의 컴포넌트 화하여 코드의 단순화와 가독성 증대
JSX 규칙
하나의 엘리먼트 안에 모든 엘리먼트가 포함되어야 함
ex) 틀린 문법
<div>
<h1>Hello</h1>
</div>
<div>
<h2>World</h2>
</div> // 엘리먼트가 각각 나눠져 있다
ex) 맞는 문법
<div>
<div>
<h1>Hello</h1>
</div>
<div>
<h2>World</h2>
</div>
</div> // 하나의 엘리먼트(div) 안에 모든 엘리먼트가 포함되어 있다
엘리먼트 클래스 사용시, className 으로 표기
React에서 CSS class 속성을 지정하려면 className 으로 표기해야 한다
→ 만약 class 로 작성하면 React에서는 이를 html 클래스 속성이 아니라 자바스크립트 클래스로 받아들이게 되니 주의!
ex) 틀린 문법
<div class = “greeting”>Hello</div>
ex) 맞는 문법
<div className=”greeting”>Hello</div>
JavaScript 표현식 사용시 중괄호{ }
이용
JSX 에서 JavaScript를 사용하려면 꼭 중괄호{}
를 이용해야 한다
→ 중괄호를 사용하지 않으면 일반 텍스트로 인식!
function App(){
const name = ‘Josh Perez’;
return (
<div>
Hello, {name}! //{name} 으로 받아옴
</div>
);
}
사용자 정의 컴포넌트는 대문자로 시작(PascalCase)
React 엘리먼트가 JSX로 작성되면 대문자로 시작해야 함
→ 소문자로 시작하면 일반적인 HTML 엘리먼트로 인식!
→ 사용자 정의 컴포넌트: 대문자로 작성된 JSX 컴포넌트
ex) 틀린 문법
function hello() { // 틀린 부분
return <div>Hello</div>;
}
function HelloWorld() {
return <hello />; // 틀린 부분
}
ex) 맞는 문법
function Hello() { // 맞는 부분
return <div>Hello</div>;
}
function HelloWorld() {
return <Hello />; // 맞는 부분
}
조건부 렌더링에는 삼항연산자 사용
조건부 렌더링(조건식) 에는 if문이 아닌 삼항연산자를 이용해야 함
<div>
{
(1+1===2) ? (<p>정답</p>) : (<p>탈락</p>)
}
</div>
여러 개의 HTML 엘리먼트를 표시할 때는 map() 함수 사용
map 함수를 사용할 때는 반드시 “key” JSX 속성 을 넣어야 함
→ “key” JSX 속성을 넣지 않으면 리스트의 각 항목에 key를 넣어야 한다는 경고!
const posts = [
{id: 1, title: ‘asdawsaf’ , content: ‘qweqds’ },
{id: 2, title: ‘qweqsdd’, content: ‘qweqsda’ }
];
function Blog(){
const content = posts.map((post) =>
<div key={post.id}> // 반드시 key 속성을 넣어야 함!
<h3>{post.title}</h3>
<p>{post.content}</p>
</div>
);
return (
<div>
{content}
</div>
);
}
map을 이용한 반복 hands-on
React에서 여러 데이터를 렌더링 할 때 사용하는 map 메소드(Array 메소드)
map을 이용한 반복
고차함수 map 메소드의 특성을 떠올려 보자
* 배열의 각 요소를
* 특정 논리(함수)에 의해
* 다른 요소로 지정(map) 한다
→ 반복적으로 작성해야 하는 부분을 골라서 배열의 요소로 넣으면 된다
ex) 배열 메소드 map 활용
function Blog() {
const postToElement = (post) => ( // 반복되는 요소를 추려서
<div>
<h3>{post.title}</h3>
<p>{post.content}</p>
</div>
);
const blogs = posts.map(postToElement); // 배열의 요소로~
return <div className="post-wrapper">{blogs}</div>;
}
return 문 안에서 map 메소드를 사용할 수는 없을까?
사용할 수 있습니다. JSX를 사용하면 중괄호 안에 모든 표현식을 포함할 수 있기 때문에 map 메소드의 결과를 return문 안에 인라인으로 처리할 수 있습니다. 코드 가독성을 위해 변수로 추출할지 아니면 인라인에 넣을지는 개발자가 판단해야 할 몫입니다.
key 속성
React에서 map 메소드 사용 시, key 속성을 넣지 않으면 경고문이 계속 뜬다!
→ key 속성의 위치는 map 메소드 내부에 있는 엘리먼트 즉, 첫 엘리먼트에 넣기!
key 속성 값이 반드시 id가 되어야 하나요? id가 존재하지 않으면 어떻게 해야 하나요?
key 속성값은 가능하면 데이터에서 제공하는 id를 할당해야 합니다. key 속성값은 id와 마찬가지로 변하지 않고, 예상 가능하며, 유일해야 하기 때문입니다. 정 고유한 id가 없는 경우에만 배열 인덱스를 넣어서 해결할 수 있습니다. 배열 인덱스는 최후의 수단(as a last resort)으로만 사용합니다. 리액트 공식문서의 key에서 추가로 공부하세요.
ex) 올바른 key 속성 값 할당의 예
function Blog() {
// postToElement라는 함수로 나누지 않고 아래와 같이 써도 무방합니다.
const blogs = posts.map((post) => (
<div key={post.id}>
<h3>{post.title}</h3>
<p>{post.content}</p>
</div>
));
return <div className="post-wrapper">{blogs}</div>;
}
→ 함수 작성할 때는 화살표 함수 방식으로 써야 하는 듯 하다?
→ React에서는 중괄호({}) 로 묶으면 function () {}와 같으며, 소괄호(())로 묶으면 () 안의 값이 return값이 됨(따로 return 표기를 안해 줘도 됨)
Component
모든 React 어플은 최소 1개의 컴포넌트를 가지고 있으며, 이 컴포넌트는 애플리케이션 내부적으로는 근원(root)이 되는 역할
이 최상위 컴포넌트는 root 므로 다른 자식 컴포넌트를 가질 수 있다
→ 계층적 구조를 트리 구조로 형상화 가능
기존의 방식과 다르게 컴포넌트화 하면 기존의 코드를 수정 작업할 때도 상호 독립적이므로 다른 컴포넌트 쪽에 영향을 적게 준다!
Create React App
학습 목표
* Create React App 소개를 보고 유추하기
* npx create-react-app: 새로운 리액트 프로젝트 시작
* create-react-app: 간단한 개발용 React 앱 실행
* 리액트 랜덤 명언 앱 hands-on 실습
* Create React App 으로 만들어진 리액트 프로젝트 구성 파악하기
Create React App?
리액트 SPA(Single Page Application)를 쉽고 빠르게 개발할 수 있도록 만들어진 툴 체인
터미널 실습
> npx create-react-app 만들프로젝트명 // 이 형식으로 프로젝트 생성 가능
→ Happy hacking! // 이 문구가 뜨면 정상적으로 설치 완료된 것!
리액트 랜덤 명언 앱 hands-on 실습
package.json 파일을 까보면
"scripts": {
"start": "react-scripts start", // 이 명령어를 npm run start에 지정한 것
"build": "react-scripts build", // 마찬가지
"test": "react-scripts test",
"eject": "react-scripts eject"
}
→ npm rum 명령어
로 지정한 것
src 폴더 – index.js 내에서
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
// import 해서 불러올 파일이나 패키지를 설정 가능
ReactDOM.render( // 렌더링하는 부분
// <React.StrictMode>
<App />, //리액트로 개발한(개발하는) 부분
// </React.StrictMode>,
document.getElementById('root')
);
app.js 파일 내에서
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
<code>src/App.js</code> 파일을 고치고 저장하면 새로운 명언이 뜬다. // 수정된 텍스트 출력
</p>
/*<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>*/
Learn React // 아래 쪽에 출력되는 텍스트
//</a>
</header>
</div>
);
}
export default App;
이를 바탕으로 랜덤 명언 앱 작성
import logo from './logo.svg';
import './App.css';
function App() {
//명언을 넣을 목록
const proverbs = ["좌절감으로 배움을 늦추지 마라", "현재에 충실하자", "내일 죽어도 하나의 사과나무를 심겠다", "죽느냐 사느냐 그것이 문제로다", "주사위는 던져졌다", "필생즉사 필사즉생","좌절감은 사나이를 키운다"]
const randomIndex =(length) =>{
return parseInt(Math.random()*length);
}
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
<code>src/App.js</code> 파일을 고치고 저장하면 새로운 명언이 뜬다.
</p>
{proverbs[randomIndex(proverbs.length)]}
{/*랜덤명언 출력*/}
{/* <a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
> */}
{/* 좌절감으로 배움을 늦추지 마라. */}
{/* </a> */}
</header>
</div>
);
}
export default App;
React Twittler Intro
트위터 유사 앱인 트위틀러 만들기 연습
학습 목표
* 리액트, JSX 기본 문법
* 리액트, JSX로 트위틀러 하드코딩
* 컴포넌트를 먼저 개발하는 Bottom-up 개발 방식
* npm script로 기본적인 툴 사용
zoom 강의 내용 정리
조건부 렌더링
조건부 렌더링을 할 때 삼항 연산자를 이용하여 작성!
조건식? 참일때 실행값: 거짓일때 실행값
예시)
const isParkHacker = tweet.username === 'parkhacker'
const tweetUserNameClass = isParkHacker
? 'tweet__username tweet__username--purple'
: 'tweet__username';
{/* 각각의 tweet 이 렌더링 되고 있는 tag 안에서 적용되도록 작성*/}
<li className="tweet" key={tweet.id}>
<span className={tweetUserNameClass}>{tweet.username}</span>
</li>
advanced challenge 관련 생각해보기
props, state hook, onclick 사용하면 되는게 팁?
호버 속성으로 마우스 오버시 아이콘 같은거가 바뀌도록 설정하는 것도 가능?
'SE Bootcamp 내용 정리' 카테고리의 다른 글
React - 기초 - 3 (0) | 2021.09.17 |
---|---|
React - 기초 - 2 (0) | 2021.09.16 |
js/node – 고차 함수 (0) | 2021.09.15 |
js/browser - DOM -2 (0) | 2021.09.13 |
js/browser - 유효성 검사 실습 (0) | 2021.09.10 |