자바 스크립트
👉 JS 프레임워크 : Angular, Backbone.js, Derby.js, Ember.js, Ext.js, > Knockback.s, Sammy.js, PureMVC, Vue.js
👉👉 주로 MVC(Model-View-Controller) 아키텍처, MVVM(Model-View-View-Model) 아키텍처를 사용, AngularJS는 MVW(Model-View-Whatever) 아키텍처공통점 : 모델(Model)과 뷰(View)가 있다.
- 모델 : 애플리케이션에서 사용하는 데이터를 관리하는 영역
- 뷰 : 사용자에게 보이는 부분
- 사용자 작업 -> 프로그램 -> 컨트롤러 -> 모델 데이터 조회, 수정 -> 뷰에 변경된 사항 반영
💬 페이스북 : 어떤 데이터가 변할 때마다 어떤 변화를 줄지 고민하지 말고 기존 뷰를 날려 버리고 처음부터 새로 렌더링하자!
👉 CPU 점유율도 크게 증가,, 메모리도 많이 사용,,
💬 페이스북 : 앞서 설명한 방식으로 최대한 성능을 아끼고 편안한 사용자 경험을 제공하면서 구현하자!!
👉 리액트 개발
함수 :
render() { ... }
- 컴포넌트가 어떻게 생겼는지 정의하는 역할
- html 형식의 문자열을 반환하지 않고, 뷰가 어떻게 생겼고 어떻게 작동하는지에 대한 정보를 지닌 객체를 반환
- 컴포넌트 내부에 또 다른 컴포넌트가 들어갈 수 있음.
- 최상위 컴포넌트의 렌더링 작업이 끝나면 지니고 있는 정보들을 사용하여 HTML 마크업을 만들고, 이를 우리가 정하는 실제 페이지의 DOM 요소 안에 주입.
리액트에서 뷰를 업데이트 할 때 : "조화 과정을 거친다"
render
함수를 또 다시 호출하여 그 데이터를 지닌 뷰를 생성❔ DOM은 느린가?
❌ NO!
DOM 자체는 빠름
변화가 일어나면 웹 브라우저가 CSS를 다시 연산하고, 레이아웃을 구성하고, 페이지를 리페인트 하는 과정에서 시간이 허비됨.🔑 해결법
Virtual DOM 방식 사용
실제 DOM을 업데이트 할 때
1. 데이터를 업데이트하면 전체 UI를 Virtual DOM에 리렌더링
2. 이전 Virtual DOM에 있던 내용과 현재 내용을 비교
3. 바뀐 부분만 실제 DOM에 적용
✔ 오해
Virtual DOM을 사용한다고 무조건 빠른 것 X
"우리는 다음 문제를 해결하려고 리액트를 만들었습니다."
"지속적으로 데이터가 변화하는 대규모 애플리케이션 구축하기"
👉 적절한 곳에 사용해야 진가를 발휘!
리액트는 프레임워크가 아니라 라이브러리
리액트는 뷰만 신경쓰는 라이브러리이므로 기타 기능은 직접 구현하여 사용해야 함!
라이브러리
라우팅 - 리액트 라우터(react-router)
Ajax 처리 - axios, fetch
상태 관리 - 리덕스(redux), MobX
SockJS, socket.io, superagent, Relay, redux-sega, redux, redux-thunk, rezt-enroute ...
다른 웹 프레임워크나 라이브러리와 혼용도 가능
Backbone.js, AngularJS
📁 src/App.js
import logo from './logo.svg';
import './App.css';
import
구문 : 특정 파일을 불러오는 것
원래 브라우저에는 모듈을 불러와서 사용하는 기능이 없었다!
👉 Node.js에서 지원하는 기능.
👉 참고) Node.js에서는 require
구문으로 패키지를 불러올 수 있음
브라우저에서 사용하기 위해 번들러를 사용
번들러(bundler)
- 파일을 묶듯이 연결해줌
- ex) 웹팩, Parcel, browserify
리액트는 주로 웹팩 사용.- import로 모듈을 불러왔을 때 불러온 모듈을 모두 합쳐서 하나의 파일을 생성해 줌.
- src/index.js를 시작으로 필요한 파일을 다 불러와서 번들링함.
웹팩의 로더(loader)
- 파일들을 불러오는 것
create-react-app
이 대신 설정해주기 때문에 별도의 설정 필요 X- css-loader : CSS 파일을 불러옴.
- file-loader : 웹 폰트나 미디어 파일 등을 불러옴.
- babel-loader : JS 파일들을 불러오면서 최신 JS 문법으로 작성된 코드를 바벨이라는 도구를 사용하여 ES5 문법으로 변환해줌.
❔ 왜 변환하는가?
ES5 : 이전 버전의 js
버전 웹 브라우저는 최신 js 문법이 실행되지 않기 때문에 사전에 꼭 변환하여 호환해야 함.
JSX도 정식 js 문법이 아니므로 ES5 형태의 코드로 변환해야 함.
📁 src/App.js
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
App
이라는 컴포넌트를 만듬.function()
▶ 함수 컴포넌트JSX
💻 JSX
function App() {
return (
<div>
Hello <b>react</b>
</div>
);
}
🔽🔽🔽
💻 JS
function App() {
return React.createElement("div", null, "Hello ", React.createElement("b", null, "react"));
}
❔ JSX는 자바스크립트 문법이다?
❌ NO!
공식적인 자바스크립트 문법이 아니다
1. 보기 쉽고 익숙하다
2. 더욱 높은 활용도
HTML 태그를 사용할 수 있고, 컴포넌트도 JSX 안에서 작성 가능.
📁 src/index.js
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App/>
</React.StrinctMode>,
document.getElementById('root')
);
📝
ReactDOM.render
- 컴포넌트를 페이지에 렌더링하는 역할
- react-dom 모듈을 불러와 사용할 수 있음.
- 첫 번째 파라미터 : 페이지에 렌더링할 내용을 JSX 형태로 작성
- 두 번째 파라미터 : 해당 JSX를 렌더링할 document 내부 요소를 설정.
📁 src/index.js
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
📝
ReactDOM.createRoot
- React 18은 더 이상 render를 사용하지 않고 createRoot를 사용하기를 권장
- state나 props 변화가 있을 때, container가 변경되지 않더라도 계속 렌더링할 때 container를 전달했어야 했는데, 새로운 root API인 createRoot는 데이터 구조의 최상위 레벨에 있는 container를 전달하지 않아도 된다.
🔸 ReactDOM.render
const container = document.getElementById('app');
// Initial render.
ReactDOM.render(<App tab="home" />, container);
// During an update, React would access
// the root of the DOM element.
ReactDOM.render(<App tab="profile" />, container);
🔸 ReactDOM.createRoot
const container = document.getElementById('app');
// Create a root.
const root = ReactDOM.createRoot(container);
// Initial render: Render an element to the root.
root.render(<App tab="home" />);
// During an update, there's no need to pass the container again.
root.render(<App tab="profile" />);
📝
React.StrictMode
- 리액트 프로젝트에서 리액트의 레거시 기능들을 사용하지 못하게 하는 기능.
레거시 기능 : 더 이상 쓰지 않는 낡은 기능
- 문자열 ref, componenetWillMount 등 나중에는 완전히 사라지게 될 옛날 기능을 사용했을 때 경고를 출력.
▶ createRoot를 사용한 곳에서 StrictMode를 사용하면, react-router-dom v5
를 사용할 경우 제대로 작동하지 않으므로 최신 버전을 사용하거나 StricMode를 사용하지 않으면 됨.
📝 왜?
Virtual DOM에서 컴포넌트 변화를 감지해 낼 때 효율적으로 비교할 수 있도록 컴포넌트 내부는 하나의 DOM 트리 구조로 이루어져야 한다는 규칙이 있기 때문입니다.
Fragment
기능import { Fragment } from 'react';
function App() {
return (
<Fragment>
<h1>리액트 안녕!<h1>
<h2>잘 작동하니?<h2>
</Fragment>
);
}
export defualt App;
또는
import { Fragment } from 'react';
function App() {
return (
<>
<h1>리액트 안녕!<h1>
<h2>잘 작동하니?<h2>
</>
);
}
export defualt App;
{ }
로 감싸기function App() {
const name = '리액트';
return (
<>
<h1>{name} 안녕!<h1>
</>
);
}
const와 let
- const : 재선언 불가, 재할당 불가
- let : 재선언 불가, 재할당 가능
- var : scope - 함수 단위
function myFunction() { var a = "hello"; if(true) { var a = "bye"; console.log(a); // bye } console.log(a); //bye } myFunction();
- if문 바깥 : "hello"
- if문 내부 : "bye"
함수 단위 -> if문 내부에서 새로 선언했음에도 if문 밖에서 a를 조회하면 변경된 값이 나타남.
- let , const : scope - 블록 단위
function myFunction() { let a = 1; if(true) { let a = 2; console.log(a); // 2 } console.log(a); // 1 } myFunction();
블록 단위 -> if문 내부에서 선언한 a 값은 if 문 밖의 a 값을 변경하지 않음.
if
문을 사용하여 사전에 값을 설정조건부 연산자(=삼항 연산자)
를 사용function App() {
const name = '리액트';
return (
<div>
{name === '리액트' ? (
<h1>리액트입니다.</h1>
) : (
<h2>리액트가 아닙니다.</h2>
)}
</div>
);
}
export default App;
조건을 만족하지 않을 때 아예 아무것도 렌더링하지 않아야 한다면?
null
은 아무것도 나타나지 않음.false
를 렌더링할 때는 아무것도 나타나지 않음.OR(||)
연산자 사용하기function App() {
const name = undefined;
return name || '값이 undefined입니다.';
}
function App() {
const name = undefined;
return <div>{name}</div>;
}
background-color
▶ backgroundColor
<input></input>
➕ self-closing
태그 : 선언하면서 동시에 닫을 수 있는 태그
<input/>
function App() {
const name = '리액트';
return(
<>
{/* 주석은 이렇게 작성합니다. */}
<div
className="react" // 시작 태그 여러줄이면 이렇게 작성 가능 ~
>
{name}
</div>
</>
);
}
JSX는 HTML과 비슷하지만 완전히 똑같지는 않습니다. 코드로 보면 XML 형식이지만 실제로는 JS 객체이며, 용도도 다르고 문법도 조금씩 차이가 납니다.