1. 브라우저의 Flow
React의 등장에 대해 알아보기 전에 브라우저가 어떻게 동작하는지 먼저 알아보자✌️
- 유저가 브라우저에 접속
- HTML을 파싱하여 DOM tree 생성
- html외부의 css파일이나 내부의 style 태그를 파싱하여 CSSOM tree 생성
- DOM 트리와 CSSOM 트리를 병합하여 렌더트리를 구성. → 콘텐츠를 설명하는 DOM과 스타일 규칙을 설명하는 CSSOM을 병합하여 화면에 픽셀을 렌더링하기 위한 마지막 단계
- Layout(=reflow) → 렌더 트리의 노드들이 가지고 있는 스타일 정보와 속성을 이용해서 브라우저에 어떤 콘텐츠를 어느 위치에 어떤 크기로 출력할 지 결정하는 단계
- Painting → 렌더링 된 요소들에 색을 입히는 과정
- Reflow → 위의 과정을 모두 거친 뒤에 페이지가 완성된다고 해서 렌더링이 다 끝난게 아니라, 어떤 액선이나 이벤트에 따라 HTML요소 같은 것들을 수정하면 그에 영향을 받은 부모&자식 노드들을 모두 수정해야 한다. → 이때 Render Tree의 각 요소들의 크기나 위치같은 것들을 다시 계산하게 된다.
- Repainting → reflow가 끝난 후 수정됨 Render Tree에 다시 색을 입히는 과정
이런 방식으로 브라우저의 Flow가 흘러간다~~
2. React 가 뭐냐? 왜 태어났냐?
Facebook에서 제공한 웹 UI를 작업하기 위한 자바스크립트 기반 라이브러리이다.🌙
2-1. SPA(Single Page Application)
IT기술이 발전하면서 web app의 크기가 커지자, 자바스크립트 파일이 넘쳐나면서 통제가 어려워졌고, 이를 효율적으로 관리하기 위해서 여러 라이브러리(backbone.js)가 나오면서 자바스크립트 파일을 조직적으로 관리하는게 용이해졌다. 그러면서 HTML, CSS, JS중에 자바스크립트의 중요성이 점점 커지기 시작했고 그러면서 SPA가 등장하기 시작했다..
- 전통적으로 웹페이지는 모든 페이지마다 HTML, CSS, JS 파일을 각각 가지고 있어야 했고, 따라서 페이지가 이동될 때마다 3개의 파일을 모두 서버와 주고 받았기 때문에 속도가 느렸다.
- Single Page Application은 HTML, CSS, Javascript파일을 최초 1회만 로드하고, 이후에는 자바스크립트 파일을 통해 DOM또는 필요한 HTML파일을 조작하는 방식을 취한다.
- 즉, 어떤 웹사이트의 전체 페이지를 하나의 페이지에 담아 동적으로 바꿔가면서 표현하는 것. 최초 화면이 불러와지는 시기에 모든 컴포넌트드를 업로드 하고, 필요한 부분을 요청하면 그에 해당하는 부분을 json형태로 응답. 뭔가를 클릭하거나 스크롤하면, 상호작용 하기 위한 최소한의 요소 변경만 일어난다.
2-2. SPA 라우팅
라우팅이란 출발지에서 목적지까지의 경로를 결정하는 기능이다. 사용자가 A라는 화면에서 B라는 화면으로 넘어가는 과정을 관리하기 위한 기능. (예를들어) 브라우저가 화면을 전환하는 경우 **1. 브라우저 주소창에 url을 입력했을 때
- 링크를 클릭했을 때
- 뒤로가기 or 앞으로 가기 click**
SPA는 hash를 이용해 라우팅한다.
위의 그림에서 #뒤에 오는 부분을 hash라고 하는데 (우리가 아는 자료구조의 hash와는 의미가 다르다!)
hash는 URI로 그린 웹페이지 내부에서 이동하기 위해 쓰인다.
→ 해시를 이용하면 새로운 페이지를 서버에 요청하는게 아니라 현재 페이지 내부에서 이동하는 것임을 알수 있다.
- SPA의 장점
- 새로운 페이지 요청시 전체를 렌더링 하지 않고 변경되는 부분만 갱신하기 때문에 효율이 좋다.
- 새롭게 갱신되는 부분만 렌더링하기 때문에 화면 깜빡임 없이 빠른 화면이동이 가능하다.
- 반응성의 향상으로, 앱처럼 자연스러운 사용자경험 (UX)을 제공하며 모바일 사용이 증가하는 시점에+ 이는 큰 장점이 된다.
- 모듈화 또는 컴포넌트 별 개발에 용이하다.
- SPA의 단점
- 웹 애플리케이션에 필요한 정적 리소스를 한번에 다운로드 하기 때문에 초기 구동 속도가 느리다.
- SPA 구조 상 데이터 처리를 클라이언트에서 하는 경우가 많은데, 해당 로직들은 JavaScript를 통해 구현되므로 코드가 외부에 노출되는 보안적인 문제가 있다.
- 검색엔진 최적화(SEO)가 어렵다. → SPA로 빌드된 결과물을 보면, <body></body>는 텅 비어있고, javascript가 body를 바꾸기 때문에 검색엔진은 이 사이트를 비어있는 사이트로 인식하기때문.
SPA를 쉽고 확장성 있게 구현하기 위한 프레임워크가 React 이다!!
2-3. React의 특징
- Virtual DOM ◦ DOM을 조작하는 과정에서 DOM에 변화가 생기면 렌더트리를 재생성하고, 모든 요소들의 스타일들이 다시 계산되고, 레이아웃을 만들고 페인팅하는 과정이 다시 반복된다. ◦ 복잡한 SPA에서는 DOM의 변화가 더욱 빈번하게 발생하는데, 이말은 이 변화를 적용하기 위해서 브라우저가 그만큼 많은 연산을 해야한다는 뜻이고, 전체적인 프로세스를 비효율적으로 만든다. ◦ 하지만 React에서의 Virtual DOM을 이용한 DOM조작은 다르다✌️
- Virtual DOM을 이용한 DOM변화 적용
- —>레이아웃 계산과 렌더링의 규모는 커지겠지만 레이아웃 계산이 1번만 이루어지기 때문에 브라우저의 성능이 빨라진다.
- 뷰에 변화가 생김 → 실제 DOM에 적용하기 전에 Virtual DOM에 적용 → 가상돔끼리의 비교를 함 (변화 전 가상돔과 변화 후 가상돔) → 여기서의 연산이 끝나면 최종적인 변화를 하나로 묶어 실제 DOM에 한번만 반영한다!
- 단방향 데이터 바인딩
- 데이터 바인딩이 뭐여?
- 두 데이터 혹은 정보의 소스를 모두 일치시키는 기법이다. 즉, 화면에 보이는 데이터와 브라우저 메모리에 있는 데이터를 일치시키는 기법이다.
- 양방향 데이터 바인딩은 사용자 UI 데이터 변경을 감지하는 Watcher와 자바스크립트 데이터 변경을 감지하는 Watcher가 UI와 자바스크립트 데이터를 자동으로 동기화 시켜주는 방식이다.
- 하지만, 하나의 데이터 동기화에 두개의 Watcher가 사용되고, 데이터 많아지게 되면 이 데이터의 동기화를 위한 수많은 Watcher가 생성되므로, 반대로 성능 저하가 발생할 수 있다.
- 단방향 데이터 바인딩은 단 하나의 Watcher가 자바스크립트의 데이터 갱신을 감지하여 사용자의 UI 데이터를 갱신한다.
- 그리고 사용자가 UI를 통해 자바스크립트의 데이터를 갱신할 때는, 이벤트를 통해 갱신한다.
- 단방향 데이터 바인딩은 하나의 Watcher를 사용하기 때문에 양방향 데이터 바인딩이 가지는 성능적인 이슈를 해결하고 더 확실하게 데이터를 추적할 수 있게 한다.
- JSX 문법 리액트에서는 JSX라는 독특한 문법을 사용하는데, 자바스크립트와 HTML을 동시에 사용하며, HTML에 자바스크립트의 변수들을 바로 사용할 수 있는 일종의 템플릿 언어(Template language) 이다.리액트는 위와 같이 자바스크립트에서 HTML 태그를 사용할 수 있으며, 자바스크립트 변수를 HTML 태그에서 바로 호출하여 사용할 수 있다.
- const App = () => { const hello = 'Hello world!'; return <div>{hello}</div>; };
- 선언형 프로그래밍
<명령형 프로그래밍>
```jsx
<ul id=”list”></ul>
<script>
var arr = [1, 2, 3, 4, 5]
var elem = document.querySelector("#list");
for(var i = 0; i < arr.length; i ++) {
var child = document.createElement("li");
child.innerHTML = arr[i];
elem.appendChild(child);
}
</script>
// 자바스크립트를 사용하는 HTML에 새로운 리스트 아이템을 추가하는 코드
```
위의 코드는 명령형 프로그래밍으로써 새로운 리스트를 표시할 ul 태그를 생성하고 자바스크립트의 querySelector를 사용하여 표시할 위치를 가져온 후, for 문을 사용하여 하나씩 리스트에 아이템을 추가
이렇게 명령형 프로그래밍은 과정을 중심으로 프로그래밍을 하게 된다.
**< JSX를 이용한 선언형 프로그래밍>**
```jsx
const arr = [1, 2, 3, 4, 5];
return (
<ul>
{arr.map((elem) => (
<li>{elem}</li>
))}
</ul>
);
//// 자바스크립트를 사용하는 HTML에 새로운 리스트 아이템을 추가하는 코드
```
리액트의 JSX 문법을 사용하면 위와 같이 HTML안에서 map 함수를 사용하여 리스트 아이템을 추가한다.
선언형 프로그래밍은 map이 어떻게 동작하는지는 크게 신경쓰지 않고 결과에 집중하여 프로그래밍
- 컴포넌트 기반 리액트로 웹 서비스를 개발할 때 , 컴포넌트 라고 부르는 작고 고립된 코드를 사용하여 UI를 구성한다.
- 컴포넌트는 재사용을 할 수 있으며 이런 재사용을 통해 개발 생산성을 향상시킬 수 있다.
- 또한 컴포넌트는 테스트하기 쉬워 코드를 유지보수하는데도 크게 도움이 됩니다.
- const Title = () => { return <h1>Hello world</h1>; }; const Button = () => { return <button>This is a Button</button>; }; const App = () => { return ( <div> <Title /> <Button /> </div> ); };
3. Styled-Component
- CSS in JS? → 스타일 정의를 CSS 파일이 아닌 JavaScript로 작성된 컴포넌트에 바로 삽입하는 스타일 기법 → React는 JSX를 사용해서 이미 JavaScript가 HTML을 포함하고 있는 형태를 취하고 있는데, 여기에 CSS-in-JS 라이브러리만 사용하면 CSS도 손쉽게 JavaScript에 삽입할 수 있다.
- 일반 CSS 의 단점
- css와 js 파일이 분리되어 있어, 동적 스타일링이 어렵다.
- class 이름 중복 가능성이 있다.
- styled-components 의 특성 및 장점
- css가 js에 들어가 있기 때문에, 동적 스타일링이 간단하다.
- 구현 시 클래스명이 임의로 부여된다.
3-1. 설치
yarn 설치
yarn add styled-components
3-2. 기본문법
import styled from "styled-components";
//설치한 styled-components 패키지에서 styled 함수를 임포트.
//styled는 Styled Components의 근간이 되는 가장 중요한놈인데
// HTML 엘리먼트나 React 컴포넌트에 원하는 스타일을 적용하기 위해서 사용된다.
- HTML 엘리먼트를 스타일링 할 때는 모든 알려진 HTML 태그에 대해서 이미 속성이 정의되어 있기 때문에 해당 태그명의 속성에 접근
import styled from "styled-components";
styled.button`
// <button> HTML 엘리먼트에 대한 스타일 정의
`;
- React 컴포넌트를 스타일링 할 때는 해당 컴포넌트를 임포트 후 인자로 해당 컴포넌트를 넘기면 된다.
import styled from "styled-components";
import Button from "./Button";
styled(Button)`
// <Button> React 컴포넌트에 스타일 정의
`;
3-3. 고정문법
- 컴포넌트 스타일링 예시
import React from "react";
import styled from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
color: gray;
backgroud: white;
`;
function Button({ children }) {
return <StyledButton>{children}</StyledButton>;
}
- <button> HTML 엘리먼트에 원하는 스타일을 적용한 후 StyledButton 변수에 저장
- JSX 문법을 이용하여 원하는 엘리먼트에 적용.
- ++스타일이 적용된 이 버튼 컴포넌트를 다른 React 컴포넌트에서 다음과 같이 사용할 수 있다.
- import Button from "./Button"; <Button>Default Button</Button>;
3-4. 가변 스타일링 1.
- Styled Components는 React 컴포넌트에 넘어온 props에 따라 다른 스타일을 적용하는 기능을 제공.
- 자바스크립트의 || 연산자를 사용하여 props이 넘어오지 않은 경우, 기존에 정의한 기본 색상이 그대로 유지되도록 한다.
import React from "react";
import styled from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
color: ${(props) => props.color || "gray"};
background: ${(props) => props.background || "white"};
`;
// props가 넘어오면 props에 따른 스타일링, 넘어오지 않으면 기존에 정의한 기본색상 그대로 유지
function Button({ children, color, background }) {
return (
<StyledButton color={color} background={background} Î>
{children}
</StyledButton>
//Button에 넘어온 color과 background props을 <StyledButton/> 컴포넌트로 넘겨줘야 한다.
);
}
import Button from "./Button";
<Button color="green" background="pink">
Green Button
</Button>;
//핑크 배경에 초록 글자를 갖도록 스타일된 버튼
3-5. 가변 스타일링 2.
- prop에 따라 바꾸고 싶은 CSS 속성이 위와 같이 하나가 아니라 여러 개일 경우
import React from "react";
import styled, { css } from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
${(props) =>
props.primary &&
css`
color: white;
background: navy;
border-color: navy;
`}
`;
// 이렇게 && 연산자를 이용해서 여러 속성을 묶을 수 있음
function Button({ children, ...props }) {
return <StyledButton {...props}>{children}</StyledButton>;
}
//넘겨야할 prop 값이 많아질 경우, 위와 같이 ...props 구문을 사용해서 c
//hildren 외에 모든 prop을 간편하게 전달
1. 브라우저의 Flow
React의 등장에 대해 알아보기 전에 브라우저가 어떻게 동작하는지 먼저 알아보자✌️
- 유저가 브라우저에 접속
- HTML을 파싱하여 DOM tree 생성
- html외부의 css파일이나 내부의 style 태그를 파싱하여 CSSOM tree 생성
- DOM 트리와 CSSOM 트리를 병합하여 렌더트리를 구성. → 콘텐츠를 설명하는 DOM과 스타일 규칙을 설명하는 CSSOM을 병합하여 화면에 픽셀을 렌더링하기 위한 마지막 단계
- Layout(=reflow) → 렌더 트리의 노드들이 가지고 있는 스타일 정보와 속성을 이용해서 브라우저에 어떤 콘텐츠를 어느 위치에 어떤 크기로 출력할 지 결정하는 단계
- Painting → 렌더링 된 요소들에 색을 입히는 과정
- Reflow → 위의 과정을 모두 거친 뒤에 페이지가 완성된다고 해서 렌더링이 다 끝난게 아니라, 어떤 액선이나 이벤트에 따라 HTML요소 같은 것들을 수정하면 그에 영향을 받은 부모&자식 노드들을 모두 수정해야 한다. → 이때 Render Tree의 각 요소들의 크기나 위치같은 것들을 다시 계산하게 된다.
- Repainting → reflow가 끝난 후 수정됨 Render Tree에 다시 색을 입히는 과정
이런 방식으로 브라우저의 Flow가 흘러간다~~
2. React 가 뭐냐? 왜 태어났냐?
Facebook에서 제공한 웹 UI를 작업하기 위한 자바스크립트 기반 라이브러리이다.🌙
2-1. SPA(Single Page Application)
IT기술이 발전하면서 web app의 크기가 커지자, 자바스크립트 파일이 넘쳐나면서 통제가 어려워졌고, 이를 효율적으로 관리하기 위해서 여러 라이브러리(backbone.js)가 나오면서 자바스크립트 파일을 조직적으로 관리하는게 용이해졌다. 그러면서 HTML, CSS, JS중에 자바스크립트의 중요성이 점점 커지기 시작했고 그러면서 SPA가 등장하기 시작했다..
- 전통적으로 웹페이지는 모든 페이지마다 HTML, CSS, JS 파일을 각각 가지고 있어야 했고, 따라서 페이지가 이동될 때마다 3개의 파일을 모두 서버와 주고 받았기 때문에 속도가 느렸다.
- Single Page Application은 HTML, CSS, Javascript파일을 최초 1회만 로드하고, 이후에는 자바스크립트 파일을 통해 DOM또는 필요한 HTML파일을 조작하는 방식을 취한다.
- 즉, 어떤 웹사이트의 전체 페이지를 하나의 페이지에 담아 동적으로 바꿔가면서 표현하는 것. 최초 화면이 불러와지는 시기에 모든 컴포넌트드를 업로드 하고, 필요한 부분을 요청하면 그에 해당하는 부분을 json형태로 응답. 뭔가를 클릭하거나 스크롤하면, 상호작용 하기 위한 최소한의 요소 변경만 일어난다.
- 저번 스터디에서 쎄벼온 예시..메인화면에서 어떤 게시판에 들어가면 header, body, footer모두 다시 불러와짐.게시판을 클릭하면 header, footer, side등 필요없는 부분에는 변화가 일어나지 않고, 게시판 페이지가 불러져와야 할 부분에만 Ajax를 통해 요청하고 json파일로 응답을 받음.
- <SPA>
- <기존 방식>
2-2. SPA 라우팅
라우팅이란 출발지에서 목적지까지의 경로를 결정하는 기능이다. 사용자가 A라는 화면에서 B라는 화면으로 넘어가는 과정을 관리하기 위한 기능. (예를들어) 브라우저가 화면을 전환하는 경우 **1. 브라우저 주소창에 url을 입력했을 때
- 링크를 클릭했을 때
- 뒤로가기 or 앞으로 가기 click**
SPA는 hash를 이용해 라우팅한다.
위의 그림에서 #뒤에 오는 부분을 hash라고 하는데 (우리가 아는 자료구조의 hash와는 의미가 다르다!)
hash는 URI로 그린 웹페이지 내부에서 이동하기 위해 쓰인다.
- 나무위키 page example이 메인 페이지에서 <4. 문제점> 이라는 게시판으로 이동하기 위해서 click을 했다!
- <https://namu.wiki/w/SPA#s-4> //주소창에 hash를 가리키는 #s-4가 붙었다. //새로고침이 일어나지 않고 화면이 이동한 것이다.
- <https://namu.wiki/w/SPA> //나무위키의 SPA문서를 가르키는 URI이다.
→ 해시를 이용하면 새로운 페이지를 서버에 요청하는게 아니라 현재 페이지 내부에서 이동하는 것임을 알수 있다.
- SPA의 장점
- 새로운 페이지 요청시 전체를 렌더링 하지 않고 변경되는 부분만 갱신하기 때문에 효율이 좋다.
- 새롭게 갱신되는 부분만 렌더링하기 때문에 화면 깜빡임 없이 빠른 화면이동이 가능하다.
- 반응성의 향상으로, 앱처럼 자연스러운 사용자경험 (UX)을 제공하며 모바일 사용이 증가하는 시점에+ 이는 큰 장점이 된다.
- 모듈화 또는 컴포넌트 별 개발에 용이하다.
- SPA의 단점
- 웹 애플리케이션에 필요한 정적 리소스를 한번에 다운로드 하기 때문에 초기 구동 속도가 느리다.
- SPA 구조 상 데이터 처리를 클라이언트에서 하는 경우가 많은데, 해당 로직들은 JavaScript를 통해 구현되므로 코드가 외부에 노출되는 보안적인 문제가 있다.
- 검색엔진 최적화(SEO)가 어렵다. → SPA로 빌드된 결과물을 보면, <body></body>는 텅 비어있고, javascript가 body를 바꾸기 때문에 검색엔진은 이 사이트를 비어있는 사이트로 인식하기때문.
SPA를 쉽고 확장성 있게 구현하기 위한 프레임워크가 React 이다!!
2-3. React의 특징
- Virtual DOM ◦ DOM을 조작하는 과정에서 DOM에 변화가 생기면 렌더트리를 재생성하고, 모든 요소들의 스타일들이 다시 계산되고, 레이아웃을 만들고 페인팅하는 과정이 다시 반복된다. ◦ 복잡한 SPA에서는 DOM의 변화가 더욱 빈번하게 발생하는데, 이말은 이 변화를 적용하기 위해서 브라우저가 그만큼 많은 연산을 해야한다는 뜻이고, 전체적인 프로세스를 비효율적으로 만든다. ◦ 하지만 React에서의 Virtual DOM을 이용한 DOM조작은 다르다✌️
- Virtual DOM을 이용한 DOM변화 적용
- —>레이아웃 계산과 렌더링의 규모는 커지겠지만 레이아웃 계산이 1번만 이루어지기 때문에 브라우저의 성능이 빨라진다.
- 뷰에 변화가 생김 → 실제 DOM에 적용하기 전에 Virtual DOM에 적용 → 가상돔끼리의 비교를 함 (변화 전 가상돔과 변화 후 가상돔) → 여기서의 연산이 끝나면 최종적인 변화를 하나로 묶어 실제 DOM에 한번만 반영한다!
- 단방향 데이터 바인딩
- 데이터 바인딩이 뭐여?
- 두 데이터 혹은 정보의 소스를 모두 일치시키는 기법이다. 즉, 화면에 보이는 데이터와 브라우저 메모리에 있는 데이터를 일치시키는 기법이다.
- 양방향 데이터 바인딩은 사용자 UI 데이터 변경을 감지하는 Watcher와 자바스크립트 데이터 변경을 감지하는 Watcher가 UI와 자바스크립트 데이터를 자동으로 동기화 시켜주는 방식이다.
- 하지만, 하나의 데이터 동기화에 두개의 Watcher가 사용되고, 데이터 많아지게 되면 이 데이터의 동기화를 위한 수많은 Watcher가 생성되므로, 반대로 성능 저하가 발생할 수 있다.
- 단방향 데이터 바인딩은 단 하나의 Watcher가 자바스크립트의 데이터 갱신을 감지하여 사용자의 UI 데이터를 갱신한다.
- 그리고 사용자가 UI를 통해 자바스크립트의 데이터를 갱신할 때는, 이벤트를 통해 갱신한다.
- 단방향 데이터 바인딩은 하나의 Watcher를 사용하기 때문에 양방향 데이터 바인딩이 가지는 성능적인 이슈를 해결하고 더 확실하게 데이터를 추적할 수 있게 한다.
- JSX 문법 리액트에서는 JSX라는 독특한 문법을 사용하는데, 자바스크립트와 HTML을 동시에 사용하며, HTML에 자바스크립트의 변수들을 바로 사용할 수 있는 일종의 템플릿 언어(Template language) 이다.리액트는 위와 같이 자바스크립트에서 HTML 태그를 사용할 수 있으며, 자바스크립트 변수를 HTML 태그에서 바로 호출하여 사용할 수 있다.
- const App = () => { const hello = 'Hello world!'; return <div>{hello}</div>; };
- 선언형 프로그래밍
<명령형 프로그래밍>
```jsx
<ul id=”list”></ul>
<script>
var arr = [1, 2, 3, 4, 5]
var elem = document.querySelector("#list");
for(var i = 0; i < arr.length; i ++) {
var child = document.createElement("li");
child.innerHTML = arr[i];
elem.appendChild(child);
}
</script>
// 자바스크립트를 사용하는 HTML에 새로운 리스트 아이템을 추가하는 코드
```
위의 코드는 명령형 프로그래밍으로써 새로운 리스트를 표시할 ul 태그를 생성하고 자바스크립트의 querySelector를 사용하여 표시할 위치를 가져온 후, for 문을 사용하여 하나씩 리스트에 아이템을 추가
이렇게 명령형 프로그래밍은 과정을 중심으로 프로그래밍을 하게 된다.
**< JSX를 이용한 선언형 프로그래밍>**
```jsx
const arr = [1, 2, 3, 4, 5];
return (
<ul>
{arr.map((elem) => (
<li>{elem}</li>
))}
</ul>
);
//// 자바스크립트를 사용하는 HTML에 새로운 리스트 아이템을 추가하는 코드
```
리액트의 JSX 문법을 사용하면 위와 같이 HTML안에서 map 함수를 사용하여 리스트 아이템을 추가한다.
선언형 프로그래밍은 map이 어떻게 동작하는지는 크게 신경쓰지 않고 결과에 집중하여 프로그래밍
- 컴포넌트 기반 리액트로 웹 서비스를 개발할 때 , 컴포넌트 라고 부르는 작고 고립된 코드를 사용하여 UI를 구성한다.
- 컴포넌트는 재사용을 할 수 있으며 이런 재사용을 통해 개발 생산성을 향상시킬 수 있다.
- 또한 컴포넌트는 테스트하기 쉬워 코드를 유지보수하는데도 크게 도움이 됩니다.
- const Title = () => { return <h1>Hello world</h1>; }; const Button = () => { return <button>This is a Button</button>; }; const App = () => { return ( <div> <Title /> <Button /> </div> ); };
3. Styled-Component
- CSS in JS? → 스타일 정의를 CSS 파일이 아닌 JavaScript로 작성된 컴포넌트에 바로 삽입하는 스타일 기법 → React는 JSX를 사용해서 이미 JavaScript가 HTML을 포함하고 있는 형태를 취하고 있는데, 여기에 CSS-in-JS 라이브러리만 사용하면 CSS도 손쉽게 JavaScript에 삽입할 수 있다.
- 일반 CSS 의 단점
- css와 js 파일이 분리되어 있어, 동적 스타일링이 어렵다.
- class 이름 중복 가능성이 있다.
- styled-components 의 특성 및 장점
- css가 js에 들어가 있기 때문에, 동적 스타일링이 간단하다.
- 구현 시 클래스명이 임의로 부여된다.
3-1. 설치
yarn 설치
yarn add styled-components
3-2. 기본문법
import styled from "styled-components";
//설치한 styled-components 패키지에서 styled 함수를 임포트.
//styled는 Styled Components의 근간이 되는 가장 중요한놈인데
// HTML 엘리먼트나 React 컴포넌트에 원하는 스타일을 적용하기 위해서 사용된다.
- HTML 엘리먼트를 스타일링 할 때는 모든 알려진 HTML 태그에 대해서 이미 속성이 정의되어 있기 때문에 해당 태그명의 속성에 접근
import styled from "styled-components";
styled.button`
// <button> HTML 엘리먼트에 대한 스타일 정의
`;
- React 컴포넌트를 스타일링 할 때는 해당 컴포넌트를 임포트 후 인자로 해당 컴포넌트를 넘기면 된다.
import styled from "styled-components";
import Button from "./Button";
styled(Button)`
// <Button> React 컴포넌트에 스타일 정의
`;
3-3. 고정문법
- 컴포넌트 스타일링 예시
import React from "react";
import styled from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
color: gray;
backgroud: white;
`;
function Button({ children }) {
return <StyledButton>{children}</StyledButton>;
}
- <button> HTML 엘리먼트에 원하는 스타일을 적용한 후 StyledButton 변수에 저장
- JSX 문법을 이용하여 원하는 엘리먼트에 적용.
- ++스타일이 적용된 이 버튼 컴포넌트를 다른 React 컴포넌트에서 다음과 같이 사용할 수 있다.
- import Button from "./Button"; <Button>Default Button</Button>;
3-4. 가변 스타일링 1.
- Styled Components는 React 컴포넌트에 넘어온 props에 따라 다른 스타일을 적용하는 기능을 제공.
- 자바스크립트의 || 연산자를 사용하여 props이 넘어오지 않은 경우, 기존에 정의한 기본 색상이 그대로 유지되도록 한다.
import React from "react";
import styled from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
color: ${(props) => props.color || "gray"};
background: ${(props) => props.background || "white"};
`;
// props가 넘어오면 props에 따른 스타일링, 넘어오지 않으면 기존에 정의한 기본색상 그대로 유지
function Button({ children, color, background }) {
return (
<StyledButton color={color} background={background} Î>
{children}
</StyledButton>
//Button에 넘어온 color과 background props을 <StyledButton/> 컴포넌트로 넘겨줘야 한다.
);
}
import Button from "./Button";
<Button color="green" background="pink">
Green Button
</Button>;
//핑크 배경에 초록 글자를 갖도록 스타일된 버튼
3-5. 가변 스타일링 2.
- prop에 따라 바꾸고 싶은 CSS 속성이 위와 같이 하나가 아니라 여러 개일 경우
import React from "react";
import styled, { css } from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
${(props) =>
props.primary &&
css`
color: white;
background: navy;
border-color: navy;
`}
`;
// 이렇게 && 연산자를 이용해서 여러 속성을 묶을 수 있음
function Button({ children, ...props }) {
return <StyledButton {...props}>{children}</StyledButton>;
}
//넘겨야할 prop 값이 많아질 경우, 위와 같이 ...props 구문을 사용해서 c
//hildren 외에 모든 prop을 간편하게 전달
1. 브라우저의 Flow
React의 등장에 대해 알아보기 전에 브라우저가 어떻게 동작하는지 먼저 알아보자✌️
- 유저가 브라우저에 접속
- HTML을 파싱하여 DOM tree 생성
- html외부의 css파일이나 내부의 style 태그를 파싱하여 CSSOM tree 생성
- DOM 트리와 CSSOM 트리를 병합하여 렌더트리를 구성. → 콘텐츠를 설명하는 DOM과 스타일 규칙을 설명하는 CSSOM을 병합하여 화면에 픽셀을 렌더링하기 위한 마지막 단계
- Layout(=reflow) → 렌더 트리의 노드들이 가지고 있는 스타일 정보와 속성을 이용해서 브라우저에 어떤 콘텐츠를 어느 위치에 어떤 크기로 출력할 지 결정하는 단계
- Painting → 렌더링 된 요소들에 색을 입히는 과정
- Reflow → 위의 과정을 모두 거친 뒤에 페이지가 완성된다고 해서 렌더링이 다 끝난게 아니라, 어떤 액선이나 이벤트에 따라 HTML요소 같은 것들을 수정하면 그에 영향을 받은 부모&자식 노드들을 모두 수정해야 한다. → 이때 Render Tree의 각 요소들의 크기나 위치같은 것들을 다시 계산하게 된다.
- Repainting → reflow가 끝난 후 수정됨 Render Tree에 다시 색을 입히는 과정
이런 방식으로 브라우저의 Flow가 흘러간다~~
2. React 가 뭐냐? 왜 태어났냐?
Facebook에서 제공한 웹 UI를 작업하기 위한 자바스크립트 기반 라이브러리이다.🌙
2-1. SPA(Single Page Application)
IT기술이 발전하면서 web app의 크기가 커지자, 자바스크립트 파일이 넘쳐나면서 통제가 어려워졌고, 이를 효율적으로 관리하기 위해서 여러 라이브러리(backbone.js)가 나오면서 자바스크립트 파일을 조직적으로 관리하는게 용이해졌다. 그러면서 HTML, CSS, JS중에 자바스크립트의 중요성이 점점 커지기 시작했고 그러면서 SPA가 등장하기 시작했다..
- 전통적으로 웹페이지는 모든 페이지마다 HTML, CSS, JS 파일을 각각 가지고 있어야 했고, 따라서 페이지가 이동될 때마다 3개의 파일을 모두 서버와 주고 받았기 때문에 속도가 느렸다.
- Single Page Application은 HTML, CSS, Javascript파일을 최초 1회만 로드하고, 이후에는 자바스크립트 파일을 통해 DOM또는 필요한 HTML파일을 조작하는 방식을 취한다.
- 즉, 어떤 웹사이트의 전체 페이지를 하나의 페이지에 담아 동적으로 바꿔가면서 표현하는 것. 최초 화면이 불러와지는 시기에 모든 컴포넌트드를 업로드 하고, 필요한 부분을 요청하면 그에 해당하는 부분을 json형태로 응답. 뭔가를 클릭하거나 스크롤하면, 상호작용 하기 위한 최소한의 요소 변경만 일어난다.
- 저번 스터디에서 쎄벼온 예시..메인화면에서 어떤 게시판에 들어가면 header, body, footer모두 다시 불러와짐.게시판을 클릭하면 header, footer, side등 필요없는 부분에는 변화가 일어나지 않고, 게시판 페이지가 불러져와야 할 부분에만 Ajax를 통해 요청하고 json파일로 응답을 받음.
- <SPA>
- <기존 방식>
2-2. SPA 라우팅
라우팅이란 출발지에서 목적지까지의 경로를 결정하는 기능이다. 사용자가 A라는 화면에서 B라는 화면으로 넘어가는 과정을 관리하기 위한 기능. (예를들어) 브라우저가 화면을 전환하는 경우 **1. 브라우저 주소창에 url을 입력했을 때
- 링크를 클릭했을 때
- 뒤로가기 or 앞으로 가기 click**
SPA는 hash를 이용해 라우팅한다.
위의 그림에서 #뒤에 오는 부분을 hash라고 하는데 (우리가 아는 자료구조의 hash와는 의미가 다르다!)
hash는 URI로 그린 웹페이지 내부에서 이동하기 위해 쓰인다.
- 나무위키 page example이 메인 페이지에서 <4. 문제점> 이라는 게시판으로 이동하기 위해서 click을 했다!
- <https://namu.wiki/w/SPA#s-4> //주소창에 hash를 가리키는 #s-4가 붙었다. //새로고침이 일어나지 않고 화면이 이동한 것이다.
- <https://namu.wiki/w/SPA> //나무위키의 SPA문서를 가르키는 URI이다.
→ 해시를 이용하면 새로운 페이지를 서버에 요청하는게 아니라 현재 페이지 내부에서 이동하는 것임을 알수 있다.
- SPA의 장점
- 새로운 페이지 요청시 전체를 렌더링 하지 않고 변경되는 부분만 갱신하기 때문에 효율이 좋다.
- 새롭게 갱신되는 부분만 렌더링하기 때문에 화면 깜빡임 없이 빠른 화면이동이 가능하다.
- 반응성의 향상으로, 앱처럼 자연스러운 사용자경험 (UX)을 제공하며 모바일 사용이 증가하는 시점에+ 이는 큰 장점이 된다.
- 모듈화 또는 컴포넌트 별 개발에 용이하다.
- SPA의 단점
- 웹 애플리케이션에 필요한 정적 리소스를 한번에 다운로드 하기 때문에 초기 구동 속도가 느리다.
- SPA 구조 상 데이터 처리를 클라이언트에서 하는 경우가 많은데, 해당 로직들은 JavaScript를 통해 구현되므로 코드가 외부에 노출되는 보안적인 문제가 있다.
- 검색엔진 최적화(SEO)가 어렵다. → SPA로 빌드된 결과물을 보면, <body></body>는 텅 비어있고, javascript가 body를 바꾸기 때문에 검색엔진은 이 사이트를 비어있는 사이트로 인식하기때문.
SPA를 쉽고 확장성 있게 구현하기 위한 프레임워크가 React 이다!!
2-3. React의 특징
- Virtual DOM ◦ DOM을 조작하는 과정에서 DOM에 변화가 생기면 렌더트리를 재생성하고, 모든 요소들의 스타일들이 다시 계산되고, 레이아웃을 만들고 페인팅하는 과정이 다시 반복된다. ◦ 복잡한 SPA에서는 DOM의 변화가 더욱 빈번하게 발생하는데, 이말은 이 변화를 적용하기 위해서 브라우저가 그만큼 많은 연산을 해야한다는 뜻이고, 전체적인 프로세스를 비효율적으로 만든다. ◦ 하지만 React에서의 Virtual DOM을 이용한 DOM조작은 다르다✌️
- Virtual DOM을 이용한 DOM변화 적용
- —>레이아웃 계산과 렌더링의 규모는 커지겠지만 레이아웃 계산이 1번만 이루어지기 때문에 브라우저의 성능이 빨라진다.
- 뷰에 변화가 생김 → 실제 DOM에 적용하기 전에 Virtual DOM에 적용 → 가상돔끼리의 비교를 함 (변화 전 가상돔과 변화 후 가상돔) → 여기서의 연산이 끝나면 최종적인 변화를 하나로 묶어 실제 DOM에 한번만 반영한다!
- 단방향 데이터 바인딩
- 데이터 바인딩이 뭐여?
- 두 데이터 혹은 정보의 소스를 모두 일치시키는 기법이다. 즉, 화면에 보이는 데이터와 브라우저 메모리에 있는 데이터를 일치시키는 기법이다.
- 양방향 데이터 바인딩은 사용자 UI 데이터 변경을 감지하는 Watcher와 자바스크립트 데이터 변경을 감지하는 Watcher가 UI와 자바스크립트 데이터를 자동으로 동기화 시켜주는 방식이다.
- 하지만, 하나의 데이터 동기화에 두개의 Watcher가 사용되고, 데이터 많아지게 되면 이 데이터의 동기화를 위한 수많은 Watcher가 생성되므로, 반대로 성능 저하가 발생할 수 있다.
- 단방향 데이터 바인딩은 단 하나의 Watcher가 자바스크립트의 데이터 갱신을 감지하여 사용자의 UI 데이터를 갱신한다.
- 그리고 사용자가 UI를 통해 자바스크립트의 데이터를 갱신할 때는, 이벤트를 통해 갱신한다.
- 단방향 데이터 바인딩은 하나의 Watcher를 사용하기 때문에 양방향 데이터 바인딩이 가지는 성능적인 이슈를 해결하고 더 확실하게 데이터를 추적할 수 있게 한다.
- JSX 문법 리액트에서는 JSX라는 독특한 문법을 사용하는데, 자바스크립트와 HTML을 동시에 사용하며, HTML에 자바스크립트의 변수들을 바로 사용할 수 있는 일종의 템플릿 언어(Template language) 이다.리액트는 위와 같이 자바스크립트에서 HTML 태그를 사용할 수 있으며, 자바스크립트 변수를 HTML 태그에서 바로 호출하여 사용할 수 있다.
- const App = () => { const hello = 'Hello world!'; return <div>{hello}</div>; };
- 선언형 프로그래밍
<명령형 프로그래밍>
```jsx
<ul id=”list”></ul>
<script>
var arr = [1, 2, 3, 4, 5]
var elem = document.querySelector("#list");
for(var i = 0; i < arr.length; i ++) {
var child = document.createElement("li");
child.innerHTML = arr[i];
elem.appendChild(child);
}
</script>
// 자바스크립트를 사용하는 HTML에 새로운 리스트 아이템을 추가하는 코드
```
위의 코드는 명령형 프로그래밍으로써 새로운 리스트를 표시할 ul 태그를 생성하고 자바스크립트의 querySelector를 사용하여 표시할 위치를 가져온 후, for 문을 사용하여 하나씩 리스트에 아이템을 추가
이렇게 명령형 프로그래밍은 과정을 중심으로 프로그래밍을 하게 된다.
**< JSX를 이용한 선언형 프로그래밍>**
```jsx
const arr = [1, 2, 3, 4, 5];
return (
<ul>
{arr.map((elem) => (
<li>{elem}</li>
))}
</ul>
);
//// 자바스크립트를 사용하는 HTML에 새로운 리스트 아이템을 추가하는 코드
```
리액트의 JSX 문법을 사용하면 위와 같이 HTML안에서 map 함수를 사용하여 리스트 아이템을 추가한다.
선언형 프로그래밍은 map이 어떻게 동작하는지는 크게 신경쓰지 않고 결과에 집중하여 프로그래밍
- 컴포넌트 기반 리액트로 웹 서비스를 개발할 때 , 컴포넌트 라고 부르는 작고 고립된 코드를 사용하여 UI를 구성한다.
- 컴포넌트는 재사용을 할 수 있으며 이런 재사용을 통해 개발 생산성을 향상시킬 수 있다.
- 또한 컴포넌트는 테스트하기 쉬워 코드를 유지보수하는데도 크게 도움이 됩니다.
- const Title = () => { return <h1>Hello world</h1>; }; const Button = () => { return <button>This is a Button</button>; }; const App = () => { return ( <div> <Title /> <Button /> </div> ); };
3. Styled-Component
- CSS in JS? → 스타일 정의를 CSS 파일이 아닌 JavaScript로 작성된 컴포넌트에 바로 삽입하는 스타일 기법 → React는 JSX를 사용해서 이미 JavaScript가 HTML을 포함하고 있는 형태를 취하고 있는데, 여기에 CSS-in-JS 라이브러리만 사용하면 CSS도 손쉽게 JavaScript에 삽입할 수 있다.
- 일반 CSS 의 단점
- css와 js 파일이 분리되어 있어, 동적 스타일링이 어렵다.
- class 이름 중복 가능성이 있다.
- styled-components 의 특성 및 장점
- css가 js에 들어가 있기 때문에, 동적 스타일링이 간단하다.
- 구현 시 클래스명이 임의로 부여된다.
3-1. 설치
yarn 설치
yarn add styled-components
3-2. 기본문법
import styled from "styled-components";
//설치한 styled-components 패키지에서 styled 함수를 임포트.
//styled는 Styled Components의 근간이 되는 가장 중요한놈인데
// HTML 엘리먼트나 React 컴포넌트에 원하는 스타일을 적용하기 위해서 사용된다.
- HTML 엘리먼트를 스타일링 할 때는 모든 알려진 HTML 태그에 대해서 이미 속성이 정의되어 있기 때문에 해당 태그명의 속성에 접근
import styled from "styled-components";
styled.button`
// <button> HTML 엘리먼트에 대한 스타일 정의
`;
- React 컴포넌트를 스타일링 할 때는 해당 컴포넌트를 임포트 후 인자로 해당 컴포넌트를 넘기면 된다.
import styled from "styled-components";
import Button from "./Button";
styled(Button)`
// <Button> React 컴포넌트에 스타일 정의
`;
3-3. 고정문법
- 컴포넌트 스타일링 예시
import React from "react";
import styled from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
color: gray;
backgroud: white;
`;
function Button({ children }) {
return <StyledButton>{children}</StyledButton>;
}
- <button> HTML 엘리먼트에 원하는 스타일을 적용한 후 StyledButton 변수에 저장
- JSX 문법을 이용하여 원하는 엘리먼트에 적용.
- ++스타일이 적용된 이 버튼 컴포넌트를 다른 React 컴포넌트에서 다음과 같이 사용할 수 있다.
- import Button from "./Button"; <Button>Default Button</Button>;
3-4. 가변 스타일링 1.
- Styled Components는 React 컴포넌트에 넘어온 props에 따라 다른 스타일을 적용하는 기능을 제공.
- 자바스크립트의 || 연산자를 사용하여 props이 넘어오지 않은 경우, 기존에 정의한 기본 색상이 그대로 유지되도록 한다.
import React from "react";
import styled from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
color: ${(props) => props.color || "gray"};
background: ${(props) => props.background || "white"};
`;
// props가 넘어오면 props에 따른 스타일링, 넘어오지 않으면 기존에 정의한 기본색상 그대로 유지
function Button({ children, color, background }) {
return (
<StyledButton color={color} background={background} Î>
{children}
</StyledButton>
//Button에 넘어온 color과 background props을 <StyledButton/> 컴포넌트로 넘겨줘야 한다.
);
}
import Button from "./Button";
<Button color="green" background="pink">
Green Button
</Button>;
//핑크 배경에 초록 글자를 갖도록 스타일된 버튼
3-5. 가변 스타일링 2.
- prop에 따라 바꾸고 싶은 CSS 속성이 위와 같이 하나가 아니라 여러 개일 경우
import React from "react";
import styled, { css } from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
${(props) =>
props.primary &&
css`
color: white;
background: navy;
border-color: navy;
`}
`;
// 이렇게 && 연산자를 이용해서 여러 속성을 묶을 수 있음
function Button({ children, ...props }) {
return <StyledButton {...props}>{children}</StyledButton>;
}
//넘겨야할 prop 값이 많아질 경우, 위와 같이 ...props 구문을 사용해서 c
//hildren 외에 모든 prop을 간편하게 전달
1. 브라우저의 Flow
React의 등장에 대해 알아보기 전에 브라우저가 어떻게 동작하는지 먼저 알아보자✌️
- 유저가 브라우저에 접속
- HTML을 파싱하여 DOM tree 생성
- html외부의 css파일이나 내부의 style 태그를 파싱하여 CSSOM tree 생성
- DOM 트리와 CSSOM 트리를 병합하여 렌더트리를 구성. → 콘텐츠를 설명하는 DOM과 스타일 규칙을 설명하는 CSSOM을 병합하여 화면에 픽셀을 렌더링하기 위한 마지막 단계
- Layout(=reflow) → 렌더 트리의 노드들이 가지고 있는 스타일 정보와 속성을 이용해서 브라우저에 어떤 콘텐츠를 어느 위치에 어떤 크기로 출력할 지 결정하는 단계
- Painting → 렌더링 된 요소들에 색을 입히는 과정
- Reflow → 위의 과정을 모두 거친 뒤에 페이지가 완성된다고 해서 렌더링이 다 끝난게 아니라, 어떤 액선이나 이벤트에 따라 HTML요소 같은 것들을 수정하면 그에 영향을 받은 부모&자식 노드들을 모두 수정해야 한다. → 이때 Render Tree의 각 요소들의 크기나 위치같은 것들을 다시 계산하게 된다.
- Repainting → reflow가 끝난 후 수정됨 Render Tree에 다시 색을 입히는 과정
이런 방식으로 브라우저의 Flow가 흘러간다~~
2. React 가 뭐냐? 왜 태어났냐?
Facebook에서 제공한 웹 UI를 작업하기 위한 자바스크립트 기반 라이브러리이다.🌙
2-1. SPA(Single Page Application)
IT기술이 발전하면서 web app의 크기가 커지자, 자바스크립트 파일이 넘쳐나면서 통제가 어려워졌고, 이를 효율적으로 관리하기 위해서 여러 라이브러리(backbone.js)가 나오면서 자바스크립트 파일을 조직적으로 관리하는게 용이해졌다. 그러면서 HTML, CSS, JS중에 자바스크립트의 중요성이 점점 커지기 시작했고 그러면서 SPA가 등장하기 시작했다..
- 전통적으로 웹페이지는 모든 페이지마다 HTML, CSS, JS 파일을 각각 가지고 있어야 했고, 따라서 페이지가 이동될 때마다 3개의 파일을 모두 서버와 주고 받았기 때문에 속도가 느렸다.
- Single Page Application은 HTML, CSS, Javascript파일을 최초 1회만 로드하고, 이후에는 자바스크립트 파일을 통해 DOM또는 필요한 HTML파일을 조작하는 방식을 취한다.
- 즉, 어떤 웹사이트의 전체 페이지를 하나의 페이지에 담아 동적으로 바꿔가면서 표현하는 것. 최초 화면이 불러와지는 시기에 모든 컴포넌트드를 업로드 하고, 필요한 부분을 요청하면 그에 해당하는 부분을 json형태로 응답. 뭔가를 클릭하거나 스크롤하면, 상호작용 하기 위한 최소한의 요소 변경만 일어난다.
- 저번 스터디에서 쎄벼온 예시..메인화면에서 어떤 게시판에 들어가면 header, body, footer모두 다시 불러와짐.게시판을 클릭하면 header, footer, side등 필요없는 부분에는 변화가 일어나지 않고, 게시판 페이지가 불러져와야 할 부분에만 Ajax를 통해 요청하고 json파일로 응답을 받음.
- <SPA>
- <기존 방식>
2-2. SPA 라우팅
라우팅이란 출발지에서 목적지까지의 경로를 결정하는 기능이다. 사용자가 A라는 화면에서 B라는 화면으로 넘어가는 과정을 관리하기 위한 기능. (예를들어) 브라우저가 화면을 전환하는 경우 **1. 브라우저 주소창에 url을 입력했을 때
- 링크를 클릭했을 때
- 뒤로가기 or 앞으로 가기 click**
SPA는 hash를 이용해 라우팅한다.
위의 그림에서 #뒤에 오는 부분을 hash라고 하는데 (우리가 아는 자료구조의 hash와는 의미가 다르다!)
hash는 URI로 그린 웹페이지 내부에서 이동하기 위해 쓰인다.
- 나무위키 page example이 메인 페이지에서 <4. 문제점> 이라는 게시판으로 이동하기 위해서 click을 했다!
- <https://namu.wiki/w/SPA#s-4> //주소창에 hash를 가리키는 #s-4가 붙었다. //새로고침이 일어나지 않고 화면이 이동한 것이다.
- <https://namu.wiki/w/SPA> //나무위키의 SPA문서를 가르키는 URI이다.
→ 해시를 이용하면 새로운 페이지를 서버에 요청하는게 아니라 현재 페이지 내부에서 이동하는 것임을 알수 있다.
- SPA의 장점
- 새로운 페이지 요청시 전체를 렌더링 하지 않고 변경되는 부분만 갱신하기 때문에 효율이 좋다.
- 새롭게 갱신되는 부분만 렌더링하기 때문에 화면 깜빡임 없이 빠른 화면이동이 가능하다.
- 반응성의 향상으로, 앱처럼 자연스러운 사용자경험 (UX)을 제공하며 모바일 사용이 증가하는 시점에+ 이는 큰 장점이 된다.
- 모듈화 또는 컴포넌트 별 개발에 용이하다.
- SPA의 단점
- 웹 애플리케이션에 필요한 정적 리소스를 한번에 다운로드 하기 때문에 초기 구동 속도가 느리다.
- SPA 구조 상 데이터 처리를 클라이언트에서 하는 경우가 많은데, 해당 로직들은 JavaScript를 통해 구현되므로 코드가 외부에 노출되는 보안적인 문제가 있다.
- 검색엔진 최적화(SEO)가 어렵다. → SPA로 빌드된 결과물을 보면, <body></body>는 텅 비어있고, javascript가 body를 바꾸기 때문에 검색엔진은 이 사이트를 비어있는 사이트로 인식하기때문.
SPA를 쉽고 확장성 있게 구현하기 위한 프레임워크가 React 이다!!
2-3. React의 특징
- Virtual DOM ◦ DOM을 조작하는 과정에서 DOM에 변화가 생기면 렌더트리를 재생성하고, 모든 요소들의 스타일들이 다시 계산되고, 레이아웃을 만들고 페인팅하는 과정이 다시 반복된다. ◦ 복잡한 SPA에서는 DOM의 변화가 더욱 빈번하게 발생하는데, 이말은 이 변화를 적용하기 위해서 브라우저가 그만큼 많은 연산을 해야한다는 뜻이고, 전체적인 프로세스를 비효율적으로 만든다. ◦ 하지만 React에서의 Virtual DOM을 이용한 DOM조작은 다르다✌️
- Virtual DOM을 이용한 DOM변화 적용
- —>레이아웃 계산과 렌더링의 규모는 커지겠지만 레이아웃 계산이 1번만 이루어지기 때문에 브라우저의 성능이 빨라진다.
- 뷰에 변화가 생김 → 실제 DOM에 적용하기 전에 Virtual DOM에 적용 → 가상돔끼리의 비교를 함 (변화 전 가상돔과 변화 후 가상돔) → 여기서의 연산이 끝나면 최종적인 변화를 하나로 묶어 실제 DOM에 한번만 반영한다!
- 단방향 데이터 바인딩
- 데이터 바인딩이 뭐여?
- 두 데이터 혹은 정보의 소스를 모두 일치시키는 기법이다. 즉, 화면에 보이는 데이터와 브라우저 메모리에 있는 데이터를 일치시키는 기법이다.
- 양방향 데이터 바인딩은 사용자 UI 데이터 변경을 감지하는 Watcher와 자바스크립트 데이터 변경을 감지하는 Watcher가 UI와 자바스크립트 데이터를 자동으로 동기화 시켜주는 방식이다.
- 하지만, 하나의 데이터 동기화에 두개의 Watcher가 사용되고, 데이터 많아지게 되면 이 데이터의 동기화를 위한 수많은 Watcher가 생성되므로, 반대로 성능 저하가 발생할 수 있다.
- 단방향 데이터 바인딩은 단 하나의 Watcher가 자바스크립트의 데이터 갱신을 감지하여 사용자의 UI 데이터를 갱신한다.
- 그리고 사용자가 UI를 통해 자바스크립트의 데이터를 갱신할 때는, 이벤트를 통해 갱신한다.
- 단방향 데이터 바인딩은 하나의 Watcher를 사용하기 때문에 양방향 데이터 바인딩이 가지는 성능적인 이슈를 해결하고 더 확실하게 데이터를 추적할 수 있게 한다.
- JSX 문법 리액트에서는 JSX라는 독특한 문법을 사용하는데, 자바스크립트와 HTML을 동시에 사용하며, HTML에 자바스크립트의 변수들을 바로 사용할 수 있는 일종의 템플릿 언어(Template language) 이다.리액트는 위와 같이 자바스크립트에서 HTML 태그를 사용할 수 있으며, 자바스크립트 변수를 HTML 태그에서 바로 호출하여 사용할 수 있다.
- const App = () => { const hello = 'Hello world!'; return <div>{hello}</div>; };
- 선언형 프로그래밍
<명령형 프로그래밍>
```jsx
<ul id=”list”></ul>
<script>
var arr = [1, 2, 3, 4, 5]
var elem = document.querySelector("#list");
for(var i = 0; i < arr.length; i ++) {
var child = document.createElement("li");
child.innerHTML = arr[i];
elem.appendChild(child);
}
</script>
// 자바스크립트를 사용하는 HTML에 새로운 리스트 아이템을 추가하는 코드
```
위의 코드는 명령형 프로그래밍으로써 새로운 리스트를 표시할 ul 태그를 생성하고 자바스크립트의 querySelector를 사용하여 표시할 위치를 가져온 후, for 문을 사용하여 하나씩 리스트에 아이템을 추가
이렇게 명령형 프로그래밍은 과정을 중심으로 프로그래밍을 하게 된다.
**< JSX를 이용한 선언형 프로그래밍>**
```jsx
const arr = [1, 2, 3, 4, 5];
return (
<ul>
{arr.map((elem) => (
<li>{elem}</li>
))}
</ul>
);
//// 자바스크립트를 사용하는 HTML에 새로운 리스트 아이템을 추가하는 코드
```
리액트의 JSX 문법을 사용하면 위와 같이 HTML안에서 map 함수를 사용하여 리스트 아이템을 추가한다.
선언형 프로그래밍은 map이 어떻게 동작하는지는 크게 신경쓰지 않고 결과에 집중하여 프로그래밍
- 컴포넌트 기반 리액트로 웹 서비스를 개발할 때 , 컴포넌트 라고 부르는 작고 고립된 코드를 사용하여 UI를 구성한다.
- 컴포넌트는 재사용을 할 수 있으며 이런 재사용을 통해 개발 생산성을 향상시킬 수 있다.
- 또한 컴포넌트는 테스트하기 쉬워 코드를 유지보수하는데도 크게 도움이 됩니다.
- const Title = () => { return <h1>Hello world</h1>; }; const Button = () => { return <button>This is a Button</button>; }; const App = () => { return ( <div> <Title /> <Button /> </div> ); };
3. Styled-Component
- CSS in JS? → 스타일 정의를 CSS 파일이 아닌 JavaScript로 작성된 컴포넌트에 바로 삽입하는 스타일 기법 → React는 JSX를 사용해서 이미 JavaScript가 HTML을 포함하고 있는 형태를 취하고 있는데, 여기에 CSS-in-JS 라이브러리만 사용하면 CSS도 손쉽게 JavaScript에 삽입할 수 있다.
- 일반 CSS 의 단점
- css와 js 파일이 분리되어 있어, 동적 스타일링이 어렵다.
- class 이름 중복 가능성이 있다.
- styled-components 의 특성 및 장점
- css가 js에 들어가 있기 때문에, 동적 스타일링이 간단하다.
- 구현 시 클래스명이 임의로 부여된다.
3-1. 설치
yarn 설치
yarn add styled-components
3-2. 기본문법
import styled from "styled-components";
//설치한 styled-components 패키지에서 styled 함수를 임포트.
//styled는 Styled Components의 근간이 되는 가장 중요한놈인데
// HTML 엘리먼트나 React 컴포넌트에 원하는 스타일을 적용하기 위해서 사용된다.
- HTML 엘리먼트를 스타일링 할 때는 모든 알려진 HTML 태그에 대해서 이미 속성이 정의되어 있기 때문에 해당 태그명의 속성에 접근
import styled from "styled-components";
styled.button`
// <button> HTML 엘리먼트에 대한 스타일 정의
`;
- React 컴포넌트를 스타일링 할 때는 해당 컴포넌트를 임포트 후 인자로 해당 컴포넌트를 넘기면 된다.
import styled from "styled-components";
import Button from "./Button";
styled(Button)`
// <Button> React 컴포넌트에 스타일 정의
`;
3-3. 고정문법
- 컴포넌트 스타일링 예시
import React from "react";
import styled from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
color: gray;
backgroud: white;
`;
function Button({ children }) {
return <StyledButton>{children}</StyledButton>;
}
- <button> HTML 엘리먼트에 원하는 스타일을 적용한 후 StyledButton 변수에 저장
- JSX 문법을 이용하여 원하는 엘리먼트에 적용.
- ++스타일이 적용된 이 버튼 컴포넌트를 다른 React 컴포넌트에서 다음과 같이 사용할 수 있다.
- import Button from "./Button"; <Button>Default Button</Button>;
3-4. 가변 스타일링 1.
- Styled Components는 React 컴포넌트에 넘어온 props에 따라 다른 스타일을 적용하는 기능을 제공.
- 자바스크립트의 || 연산자를 사용하여 props이 넘어오지 않은 경우, 기존에 정의한 기본 색상이 그대로 유지되도록 한다.
import React from "react";
import styled from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
color: ${(props) => props.color || "gray"};
background: ${(props) => props.background || "white"};
`;
// props가 넘어오면 props에 따른 스타일링, 넘어오지 않으면 기존에 정의한 기본색상 그대로 유지
function Button({ children, color, background }) {
return (
<StyledButton color={color} background={background} Î>
{children}
</StyledButton>
//Button에 넘어온 color과 background props을 <StyledButton/> 컴포넌트로 넘겨줘야 한다.
);
}
import Button from "./Button";
<Button color="green" background="pink">
Green Button
</Button>;
//핑크 배경에 초록 글자를 갖도록 스타일된 버튼
3-5. 가변 스타일링 2.
- prop에 따라 바꾸고 싶은 CSS 속성이 위와 같이 하나가 아니라 여러 개일 경우
import React from "react";
import styled, { css } from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
${(props) =>
props.primary &&
css`
color: white;
background: navy;
border-color: navy;
`}
`;
// 이렇게 && 연산자를 이용해서 여러 속성을 묶을 수 있음
function Button({ children, ...props }) {
return <StyledButton {...props}>{children}</StyledButton>;
}
//넘겨야할 prop 값이 많아질 경우, 위와 같이 ...props 구문을 사용해서 c
//hildren 외에 모든 prop을 간편하게 전달
1. 브라우저의 Flow
React의 등장에 대해 알아보기 전에 브라우저가 어떻게 동작하는지 먼저 알아보자✌️
- 유저가 브라우저에 접속
- HTML을 파싱하여 DOM tree 생성
- html외부의 css파일이나 내부의 style 태그를 파싱하여 CSSOM tree 생성
- DOM 트리와 CSSOM 트리를 병합하여 렌더트리를 구성. → 콘텐츠를 설명하는 DOM과 스타일 규칙을 설명하는 CSSOM을 병합하여 화면에 픽셀을 렌더링하기 위한 마지막 단계
- Layout(=reflow) → 렌더 트리의 노드들이 가지고 있는 스타일 정보와 속성을 이용해서 브라우저에 어떤 콘텐츠를 어느 위치에 어떤 크기로 출력할 지 결정하는 단계
- Painting → 렌더링 된 요소들에 색을 입히는 과정
- Reflow → 위의 과정을 모두 거친 뒤에 페이지가 완성된다고 해서 렌더링이 다 끝난게 아니라, 어떤 액선이나 이벤트에 따라 HTML요소 같은 것들을 수정하면 그에 영향을 받은 부모&자식 노드들을 모두 수정해야 한다. → 이때 Render Tree의 각 요소들의 크기나 위치같은 것들을 다시 계산하게 된다.
- Repainting → reflow가 끝난 후 수정됨 Render Tree에 다시 색을 입히는 과정
이런 방식으로 브라우저의 Flow가 흘러간다~~
2. React 가 뭐냐? 왜 태어났냐?
Facebook에서 제공한 웹 UI를 작업하기 위한 자바스크립트 기반 라이브러리이다.🌙
2-1. SPA(Single Page Application)
IT기술이 발전하면서 web app의 크기가 커지자, 자바스크립트 파일이 넘쳐나면서 통제가 어려워졌고, 이를 효율적으로 관리하기 위해서 여러 라이브러리(backbone.js)가 나오면서 자바스크립트 파일을 조직적으로 관리하는게 용이해졌다. 그러면서 HTML, CSS, JS중에 자바스크립트의 중요성이 점점 커지기 시작했고 그러면서 SPA가 등장하기 시작했다..
- 전통적으로 웹페이지는 모든 페이지마다 HTML, CSS, JS 파일을 각각 가지고 있어야 했고, 따라서 페이지가 이동될 때마다 3개의 파일을 모두 서버와 주고 받았기 때문에 속도가 느렸다.
- Single Page Application은 HTML, CSS, Javascript파일을 최초 1회만 로드하고, 이후에는 자바스크립트 파일을 통해 DOM또는 필요한 HTML파일을 조작하는 방식을 취한다.
- 즉, 어떤 웹사이트의 전체 페이지를 하나의 페이지에 담아 동적으로 바꿔가면서 표현하는 것. 최초 화면이 불러와지는 시기에 모든 컴포넌트드를 업로드 하고, 필요한 부분을 요청하면 그에 해당하는 부분을 json형태로 응답. 뭔가를 클릭하거나 스크롤하면, 상호작용 하기 위한 최소한의 요소 변경만 일어난다.
- 저번 스터디에서 쎄벼온 예시..메인화면에서 어떤 게시판에 들어가면 header, body, footer모두 다시 불러와짐.게시판을 클릭하면 header, footer, side등 필요없는 부분에는 변화가 일어나지 않고, 게시판 페이지가 불러져와야 할 부분에만 Ajax를 통해 요청하고 json파일로 응답을 받음.
- <SPA>
- <기존 방식>
2-2. SPA 라우팅
라우팅이란 출발지에서 목적지까지의 경로를 결정하는 기능이다. 사용자가 A라는 화면에서 B라는 화면으로 넘어가는 과정을 관리하기 위한 기능. (예를들어) 브라우저가 화면을 전환하는 경우 **1. 브라우저 주소창에 url을 입력했을 때
- 링크를 클릭했을 때
- 뒤로가기 or 앞으로 가기 click**
SPA는 hash를 이용해 라우팅한다.
위의 그림에서 #뒤에 오는 부분을 hash라고 하는데 (우리가 아는 자료구조의 hash와는 의미가 다르다!)
hash는 URI로 그린 웹페이지 내부에서 이동하기 위해 쓰인다.
- 나무위키 page example이 메인 페이지에서 <4. 문제점> 이라는 게시판으로 이동하기 위해서 click을 했다!
- <https://namu.wiki/w/SPA#s-4> //주소창에 hash를 가리키는 #s-4가 붙었다. //새로고침이 일어나지 않고 화면이 이동한 것이다.
- <https://namu.wiki/w/SPA> //나무위키의 SPA문서를 가르키는 URI이다.
→ 해시를 이용하면 새로운 페이지를 서버에 요청하는게 아니라 현재 페이지 내부에서 이동하는 것임을 알수 있다.
- SPA의 장점
- 새로운 페이지 요청시 전체를 렌더링 하지 않고 변경되는 부분만 갱신하기 때문에 효율이 좋다.
- 새롭게 갱신되는 부분만 렌더링하기 때문에 화면 깜빡임 없이 빠른 화면이동이 가능하다.
- 반응성의 향상으로, 앱처럼 자연스러운 사용자경험 (UX)을 제공하며 모바일 사용이 증가하는 시점에+ 이는 큰 장점이 된다.
- 모듈화 또는 컴포넌트 별 개발에 용이하다.
- SPA의 단점
- 웹 애플리케이션에 필요한 정적 리소스를 한번에 다운로드 하기 때문에 초기 구동 속도가 느리다.
- SPA 구조 상 데이터 처리를 클라이언트에서 하는 경우가 많은데, 해당 로직들은 JavaScript를 통해 구현되므로 코드가 외부에 노출되는 보안적인 문제가 있다.
- 검색엔진 최적화(SEO)가 어렵다. → SPA로 빌드된 결과물을 보면, <body></body>는 텅 비어있고, javascript가 body를 바꾸기 때문에 검색엔진은 이 사이트를 비어있는 사이트로 인식하기때문.
SPA를 쉽고 확장성 있게 구현하기 위한 프레임워크가 React 이다!!
2-3. React의 특징
- Virtual DOM ◦ DOM을 조작하는 과정에서 DOM에 변화가 생기면 렌더트리를 재생성하고, 모든 요소들의 스타일들이 다시 계산되고, 레이아웃을 만들고 페인팅하는 과정이 다시 반복된다. ◦ 복잡한 SPA에서는 DOM의 변화가 더욱 빈번하게 발생하는데, 이말은 이 변화를 적용하기 위해서 브라우저가 그만큼 많은 연산을 해야한다는 뜻이고, 전체적인 프로세스를 비효율적으로 만든다. ◦ 하지만 React에서의 Virtual DOM을 이용한 DOM조작은 다르다✌️
- Virtual DOM을 이용한 DOM변화 적용
- —>레이아웃 계산과 렌더링의 규모는 커지겠지만 레이아웃 계산이 1번만 이루어지기 때문에 브라우저의 성능이 빨라진다.
- 뷰에 변화가 생김 → 실제 DOM에 적용하기 전에 Virtual DOM에 적용 → 가상돔끼리의 비교를 함 (변화 전 가상돔과 변화 후 가상돔) → 여기서의 연산이 끝나면 최종적인 변화를 하나로 묶어 실제 DOM에 한번만 반영한다!
- 단방향 데이터 바인딩
- 데이터 바인딩이 뭐여?
- 두 데이터 혹은 정보의 소스를 모두 일치시키는 기법이다. 즉, 화면에 보이는 데이터와 브라우저 메모리에 있는 데이터를 일치시키는 기법이다.
- 양방향 데이터 바인딩은 사용자 UI 데이터 변경을 감지하는 Watcher와 자바스크립트 데이터 변경을 감지하는 Watcher가 UI와 자바스크립트 데이터를 자동으로 동기화 시켜주는 방식이다.
- 하지만, 하나의 데이터 동기화에 두개의 Watcher가 사용되고, 데이터 많아지게 되면 이 데이터의 동기화를 위한 수많은 Watcher가 생성되므로, 반대로 성능 저하가 발생할 수 있다.
- 단방향 데이터 바인딩은 단 하나의 Watcher가 자바스크립트의 데이터 갱신을 감지하여 사용자의 UI 데이터를 갱신한다.
- 그리고 사용자가 UI를 통해 자바스크립트의 데이터를 갱신할 때는, 이벤트를 통해 갱신한다.
- 단방향 데이터 바인딩은 하나의 Watcher를 사용하기 때문에 양방향 데이터 바인딩이 가지는 성능적인 이슈를 해결하고 더 확실하게 데이터를 추적할 수 있게 한다.
- JSX 문법 리액트에서는 JSX라는 독특한 문법을 사용하는데, 자바스크립트와 HTML을 동시에 사용하며, HTML에 자바스크립트의 변수들을 바로 사용할 수 있는 일종의 템플릿 언어(Template language) 이다.리액트는 위와 같이 자바스크립트에서 HTML 태그를 사용할 수 있으며, 자바스크립트 변수를 HTML 태그에서 바로 호출하여 사용할 수 있다.
- const App = () => { const hello = 'Hello world!'; return <div>{hello}</div>; };
- 선언형 프로그래밍
<명령형 프로그래밍>
```jsx
<ul id=”list”></ul>
<script>
var arr = [1, 2, 3, 4, 5]
var elem = document.querySelector("#list");
for(var i = 0; i < arr.length; i ++) {
var child = document.createElement("li");
child.innerHTML = arr[i];
elem.appendChild(child);
}
</script>
// 자바스크립트를 사용하는 HTML에 새로운 리스트 아이템을 추가하는 코드
```
위의 코드는 명령형 프로그래밍으로써 새로운 리스트를 표시할 ul 태그를 생성하고 자바스크립트의 querySelector를 사용하여 표시할 위치를 가져온 후, for 문을 사용하여 하나씩 리스트에 아이템을 추가
이렇게 명령형 프로그래밍은 과정을 중심으로 프로그래밍을 하게 된다.
**< JSX를 이용한 선언형 프로그래밍>**
```jsx
const arr = [1, 2, 3, 4, 5];
return (
<ul>
{arr.map((elem) => (
<li>{elem}</li>
))}
</ul>
);
//// 자바스크립트를 사용하는 HTML에 새로운 리스트 아이템을 추가하는 코드
```
리액트의 JSX 문법을 사용하면 위와 같이 HTML안에서 map 함수를 사용하여 리스트 아이템을 추가한다.
선언형 프로그래밍은 map이 어떻게 동작하는지는 크게 신경쓰지 않고 결과에 집중하여 프로그래밍
- 컴포넌트 기반 리액트로 웹 서비스를 개발할 때 , 컴포넌트 라고 부르는 작고 고립된 코드를 사용하여 UI를 구성한다.
- 컴포넌트는 재사용을 할 수 있으며 이런 재사용을 통해 개발 생산성을 향상시킬 수 있다.
- 또한 컴포넌트는 테스트하기 쉬워 코드를 유지보수하는데도 크게 도움이 됩니다.
- const Title = () => { return <h1>Hello world</h1>; }; const Button = () => { return <button>This is a Button</button>; }; const App = () => { return ( <div> <Title /> <Button /> </div> ); };
3. Styled-Component
- CSS in JS? → 스타일 정의를 CSS 파일이 아닌 JavaScript로 작성된 컴포넌트에 바로 삽입하는 스타일 기법 → React는 JSX를 사용해서 이미 JavaScript가 HTML을 포함하고 있는 형태를 취하고 있는데, 여기에 CSS-in-JS 라이브러리만 사용하면 CSS도 손쉽게 JavaScript에 삽입할 수 있다.
- 일반 CSS 의 단점
- css와 js 파일이 분리되어 있어, 동적 스타일링이 어렵다.
- class 이름 중복 가능성이 있다.
- styled-components 의 특성 및 장점
- css가 js에 들어가 있기 때문에, 동적 스타일링이 간단하다.
- 구현 시 클래스명이 임의로 부여된다.
3-1. 설치
yarn 설치
yarn add styled-components
3-2. 기본문법
import styled from "styled-components";
//설치한 styled-components 패키지에서 styled 함수를 임포트.
//styled는 Styled Components의 근간이 되는 가장 중요한놈인데
// HTML 엘리먼트나 React 컴포넌트에 원하는 스타일을 적용하기 위해서 사용된다.
- HTML 엘리먼트를 스타일링 할 때는 모든 알려진 HTML 태그에 대해서 이미 속성이 정의되어 있기 때문에 해당 태그명의 속성에 접근
import styled from "styled-components";
styled.button`
// <button> HTML 엘리먼트에 대한 스타일 정의
`;
- React 컴포넌트를 스타일링 할 때는 해당 컴포넌트를 임포트 후 인자로 해당 컴포넌트를 넘기면 된다.
import styled from "styled-components";
import Button from "./Button";
styled(Button)`
// <Button> React 컴포넌트에 스타일 정의
`;
3-3. 고정문법
- 컴포넌트 스타일링 예시
import React from "react";
import styled from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
color: gray;
backgroud: white;
`;
function Button({ children }) {
return <StyledButton>{children}</StyledButton>;
}
- <button> HTML 엘리먼트에 원하는 스타일을 적용한 후 StyledButton 변수에 저장
- JSX 문법을 이용하여 원하는 엘리먼트에 적용.
- ++스타일이 적용된 이 버튼 컴포넌트를 다른 React 컴포넌트에서 다음과 같이 사용할 수 있다.
- import Button from "./Button"; <Button>Default Button</Button>;
3-4. 가변 스타일링 1.
- Styled Components는 React 컴포넌트에 넘어온 props에 따라 다른 스타일을 적용하는 기능을 제공.
- 자바스크립트의 || 연산자를 사용하여 props이 넘어오지 않은 경우, 기존에 정의한 기본 색상이 그대로 유지되도록 한다.
import React from "react";
import styled from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
color: ${(props) => props.color || "gray"};
background: ${(props) => props.background || "white"};
`;
// props가 넘어오면 props에 따른 스타일링, 넘어오지 않으면 기존에 정의한 기본색상 그대로 유지
function Button({ children, color, background }) {
return (
<StyledButton color={color} background={background} Î>
{children}
</StyledButton>
//Button에 넘어온 color과 background props을 <StyledButton/> 컴포넌트로 넘겨줘야 한다.
);
}
import Button from "./Button";
<Button color="green" background="pink">
Green Button
</Button>;
//핑크 배경에 초록 글자를 갖도록 스타일된 버튼
3-5. 가변 스타일링 2.
- prop에 따라 바꾸고 싶은 CSS 속성이 위와 같이 하나가 아니라 여러 개일 경우
import React from "react";
import styled, { css } from "styled-components";
const StyledButton = styled.button`
padding: 0.375rem 0.75rem;
border-radius: 0.25rem;
font-size: 1rem;
line-height: 1.5;
border: 1px solid lightgray;
${(props) =>
props.primary &&
css`
color: white;
background: navy;
border-color: navy;
`}
`;
// 이렇게 && 연산자를 이용해서 여러 속성을 묶을 수 있음
function Button({ children, ...props }) {
return <StyledButton {...props}>{children}</StyledButton>;
}
//넘겨야할 prop 값이 많아질 경우, 위와 같이 ...props 구문을 사용해서 c
//hildren 외에 모든 prop을 간편하게 전달
'Front-end > JavaScript' 카테고리의 다른 글
[JavaScript] 재귀와 스택 (recursion & stack) (0) | 2022.05.08 |
---|---|
[JavaScript] 재귀함수 호출 예시 (0) | 2022.05.08 |
[Javascript] 참조에 의한 객체 복사 (0) | 2022.04.18 |
[Javascript] 객체란 무엇인가? (0) | 2022.04.17 |
[Javascript] querySelectorAll 에 addEventListener 적용하기 (0) | 2022.04.15 |