티스토리 뷰
제로초님의 React 기본 강좌 강의를 보고 배운 내용을 정리합니다.
https://www.youtube.com/watch?v=V3QsSrldHqI&list=PLcqDmjxt30RtqbStQqk-eYMK8N-1SYIFn
2-1. React Hooks 사용하기
· Functional Component
setState와 ref를 사용하지 않을 때 Functional Component를 사용한다. (Hooks는 아니다.)
const Hello = () => {
return (
<div>Hello</div>
);
}
· React Hooks state 사용
Functional Component에서 setState와 ref를 사용할 수 있도록 만든 것이다.
state 선언
이 방식을 비구조화 할당 또는 구조 분해 할당이라고 부른다.
this.state = {
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
result: '',
};
const [first, setFrist] = React.useState(Math.ceil(Math.random() * 9));
const [second, setSecond] = React.useState(Math.ceil(Math.random() * 9));
const [value, setValue] = React.useState('');
const [result, setResult] = React.useState('');
state 사용
render() {
return (
<React.Fragment>
<div>{this.state.first} 곱하기 {this.state.second} ?</div>
<form>
<inputtype="number" value={this.state.value} />
<button>send</button>
</form>
<div>{this.state.result}</div>
</React.Fragment>
);
}
return (
<React.Fragment>
<div>{first} 곱하기 {second} ?</div>
<form>
<input type="number" value={value} />
<button>submit</button>
</form>
<div>{result}</div>
</React.Fragment>
);
state 변경
this.setState({
value: '29',
result: '30',
});
setValue('29');
setResult('30');
· React Hooks ref 사용
onSubmit = (event) => {
event.preventDefault();
this.input.focus();
}
input;
onRefInput = (c) => {
this.input = c;
}
render() {
return (
<React.Fragment>
<form onSubmit={this.onSubmit}>
<input ref={this.onRefInput} type="number" />
</form>
</React.Fragment>
);
}
const inputRef = React.useRef(null);
onSubmit = (event) => {
event.preventDefault();
inputRef.current.focus();
}
return (
<React.Fragment>
<form onSubmit={onSubmit}>
<input ref={inputRef} type="number" />
</form>
</React.Fragment>
);
2-2. Class와 Hooks 비교하기
· Rendering
class는 setState를 통해 값이 변경되면 render만 새로 실행되지만 Hooks는 Component 전체가 새로 실행된다.
(여기서부터 - 여기까지)
/* Class */
class Gugudan extends React.Component {
constructor(props) {
super(props);
this.state = {
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
result: '',
};
}
onSubmit = (event) => {
event.preventDefault();
if (parseInt(this.state.value) === this.state.first * this.state.second) {
this.setState((prevState) => {
return {
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
result: '정답 : ' + this.state.value + ' 딩동댕',
}
});
} else {
this.setState((prevState) => {
return {
value: '',
result: '정답 : ' + prevState.value + ' 띵똥땡',
}
});
}
this.input.focus();
}
onChange = (event) => {
this.setState({
value: event.target.value
});
}
input;
onRefInput = (c) => {
this.input = c;
}
// 여기서부터
render() {
return (
<React.Fragment>
<div>{this.state.first} 곱하기 {this.state.second} ?</div>
<form onSubmit={this.onSubmit}>
<input ref={this.onRefInput} type="number" value={this.state.value} onChange={this.onChange} />
<button>send</button>
</form>
<div>{this.state.result}</div>
</React.Fragment>
);
}
// 여기까지
}
/* Hooks */
// 여기서부터
const Gugudan = () => {
const [first, setFrist] = React.useState(Math.ceil(Math.random() * 9));
const [second, setSecond] = React.useState(Math.ceil(Math.random() * 9));
const [value, setValue] = React.useState('');
const [result, setResult] = React.useState('');
const inputRef = React.useRef(null);
const onSubmitForm = (event) => {
event.preventDefault();
if (parseInt(value) === (first * second)) {
setFrist(Math.ceil(Math.random() * 9));
setSecond(Math.ceil(Math.random() * 9));
setValue('');
setResult('정답 : ' + value + ' 딩동댕');
} else {
setValue('');
setResult('정답 : ' + value + ' 띵똥땡');
}
inputRef.current.focus();
}
const onChangeInput = (event) => {
setValue(event.target.value);
}
return (
<React.Fragment>
<div>{first} 곱하기 {second} ?</div>
<form onSubmit={onSubmitForm}>
<input ref={inputRef} type="number" value={value} onChange={onChangeInput} />
<button>submit</button>
</form>
<div>{result}</div>
</React.Fragment>
);
}
// 여기까지
· HTML 속성
JavaScript 엔진이 Class Component와 헷갈려하기 때문에 React에서는 HTML 속성으로 class를 사용할 수 없다.
또한 <label> 태그에 for 속성도 for문과 헷갈려하기 때문에 사용할 수 없다.
class → className
for → htmlFor
· state 객체
Hooks에서 state를 객체형으로 사용할 수 있다.
하지만 setState를 통해 값을 변경할 때 모든 state를 지정해주어야 한다. 지정해주지 않은 state는 빈 값이 된다.
state 객체 선언
const [state, setState] = React.useState({
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
result: '',
});
state 객체 사용
<div>{state.result}</div>
state 객체 변경
위 방식일 때는 상관없지만, 아래 방식일 때 지정해주지 않는 first와 second의 state는 빈 값이 된다.
setState({
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
result: '정답 : ' + this.state.value + ' 딩동댕',
});
setState({
value: '',
result: '정답 : ' + prevState.value + ' 띵똥땡',
});
· return state
함수를 적어 인자 값으로 현재(이전) state를 받을 수 있다.
setCounter((prevCounter) => {
return prevCounter + 1
});
· 비동기 렌더링
setState를 할 때마다 렌더링이 새로 실행되는데 React는 비동기이기 때문에 아래와 같은 상황에서 4번 렌더링이 아닌 1번만 렌더링이 된다.
if (parseInt(value) === (first * second)) {
setFrist(Math.ceil(Math.random() * 9)); // 1
setSecond(Math.ceil(Math.random() * 9)); // 2
setValue(''); // 3
setResult('정답 : ' + value + ' 딩동댕'); // 4
}
2-3. 웹팩 설치하기
· webpack
여러 개의 자바스크립트 파일을 합쳐서 1개의 자바스크립트 파일로 만들어준다.
terminal
// node와 npm 설치된 상태
> npm init
> npm i react react-dom
> npm i -D webpack webpack-cli // 개발에서만 사용할 때 '-D'를 붙힌다.
TMI !
1. FaceBook에 Component는 2만 개다.
2. 개발자의 원칙은 중복을 제거하는 것이다.
3. node(노드)는 자바스크립트 실행기이다.
2-4. 모듈 시스템과 웹팩 설정
· module
파일을 모듈 시스템으로 만들면 필요한 모듈(파일)만 불러와서 사용할 수 있다.
· webpack.config.js
resolve
entry 파일 확장자를 미리 적어서 entry에서 파일 확장자를 적어주지 않아도 된다.
entry
client.jsx에서 WordRelay.jsx를 불러올 경우 입력에 WordRelay를 적어주지 않아도 된다.
output
entry 파일을 한 개의 파일로 합쳐 app.js로 만든다.
const path = require('path');
module.exports = {
name: 'word-relay-setting',
// 배포 : production
mode: 'development',
// 배포 : hidden-source-map
devtool: 'eval',
resolve: {
extensions: [
'.js',
'.jsx',
]
},
// 입력
entry: {
app: [
'./client',
//'./WordRelay',
]
},
// 출력
output: {
path: path.join(__dirname, 'dist'),
filename: 'app.js',
},
};
2-5. 웹팩으로 빌드하기
· webpack 실행
cmd 창에 webpack 명령어를 입력하면 다음과 같은 오류가 출력된다.
cmd에서 webpack을 실행할 수 있도록 명령어 등록이 필요하다.
D:\reactjs\react-basic\03. 끝말잇기> webpack
'webpack'은(는) 내부 또는 외부 명형, 실행할 수 있는 프로그램, 또는
배치 파일이 아닙니다.
명령어 등록
1. package.json에 scripts 등록
// 부분 생략
{
"name": "lecture",
"main": "index.js",
"scripts": {
//"명령어": "실행시킬 프로그램"
"dev": "webpack"
},
"author": "BoHee Park",
"license": "MIT",
}
// npm run 뒤에 scripts에 적어놓은 명령어를 입력한다.
D:\reactjs\react-basic\03. 끝말잇기> npm run dev
2. npx 사용
D:\reactjs\react-basic\03. 끝말잇기> npx webpack
· 에러
위 명령어를 입력했을 때, webpack이 jsx 문법을 이해하지 못해 생긴 에러이다.
ERROR in ./client.jsx 6:16
Module parse failed: Unexpected token (6:16)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| const WordRelay = require('./WordRelay');
|
> ReactDOM.render(<WordRelay />, document.querySelector('#root'));
@ multi ./client app[0]
바벨을 install 해주어야 한다.
> npm i -D @babel/core @babel/preset-env @babel/preset-react @babel/plugin-proposal-class-properties babel-loader
· babel
webpack에서 jsx를 실행할 수 있도록 babel을 install 한다.
// 부분 생략
{
"devDependencies": {
// babel에 기본, 최신 문법을 이전 문법으로 변환
"@babel/core": "^7.7.5",
// browser에 맞게 이전 문법 적용
"@babel/preset-env": "^7.7.6",
// jsx 지원
"@babel/preset-react": "^7.7.4",
// webpack과 babel 연결
"babel-loader": "^8.0.6",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10"
}
}
babel 사용
webpack.config.js에서 babel을 사용할 수 있도록 module을 설정한다.
// 부분 생략
const path = require('path');
module.exports = {
module: {
rules: [{
//js와 jsx 파일에 룰 적용
test: /\.jsx?/,
//babel 적용
loader: 'babel-loader',
//babel에 옵션
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react',
],
plugins: [
'@babel/plugin-proposal-class-properties',
],
},
}],
},
};
2-6. 구구단 웹팩으로 빌드하기
· 과정
1. npm installl
react와 webpack, babel 등 사용할 외부 모듈을 install 한다.
2. webpack.config.js
3. 코드 작성
4. 빌드
2-7. @babel/preset-env와 plugins
· preset
plugin들의 모음이다.
· @babel/preset-env의 option
option
지원할 browser만 설정한다.
사용 이유
browser가 예전 버전일수록 babel에서 최신 문법을 더 이전에 문법으로 바꿔주어야 한다.
그러면, babel의 작업량이 증가해 속도가 느려진다.
// 부분 생략
module.exports = {
name: '',
mode: '',
devtool: '',
resolve: {},
entry: {},
module: {
rules: [{
test: /\.jsx?/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
targets: {
browsers: [
// 한국에서 점유율이 5% 이하인 브라우저는 지원하지 않는다.
'> 5% in KR',
// 크롬 버전이 70이라면, 69와 70 버전만 지원한다.
'last 2 chrome versions'
],
},
debug: true,
}
],
'@babel/preset-react',
],
plugins: [],
},
}],
},
output: {},
};
using target
@babel/preset-env의 targer 설정 후, 새로 빌드했을 때 cmd를 통해 적용된 target을 알 수 있다.
// targets의 '> 5% in KR'만 적었을 때
// 한국에서 5% 이하의 점유율을 가진 browser를 제외하고 babel이 지원할 browser를 알려준다.
@babel/preset-env: `DEBUG` option
Using targets:
{
"chrome": "4",
"ie": "11",
"samsung": "10.1"
}
browser 설정 참고
https://github.com/browserslist/browserslist
· plugins
확장 프로그램(?)과 비슷하다.
// 부분 생략
const webpack = require('webpack');
module.exports = {
name: '',
mode: '',
devtool: '',
resolve: {},
entry: {},
module: {},
plugins: [
// loader의 options의 'debug: true'를 넣어준다.
new webpack.LoaderOptionsPlugin({ debug: true }),
],
output: {},
};
2-8. 끝말잇기 Class 만들기
· value와 onChange, defaultValue
<input> 태그 속성으로 value를 사용하면 onChange 속성도 사용해야 한다.
<input type="text" value={value} onChange={onChangeInput} />
value 속성을 사용하지 않으면 defaultValue를 넣어주어야 한다.
<input type="text" defaultValue={value} />
2-9. webpack-dev-server와 hot-loader
· webpack-dev-server
webpack.config.js를 읽어서 빌드를 해주고, 그것을 server로 유지한다.
http://localhost:8080/ 주소를 생성해준다.
· react-hot-loader
수정할 때마다 자동으로 빌드를 해준다.
· 자동 빌드 환경 설정
1. npm install
> npm i -D react-hot-loader
> npm i -D webpack-dev-server
2. paskage.json의 scripts 수정
// 부분 생략
{
"scripts": {
// 이전 "dev": "webpack"
"dev": "webpack-dev-server --hot"
},
"devDependencies": {
"react-hot-loader": "^4.12.18",
"webpack-dev-server": "^3.9.0"
}
}
3. js 수정
const React = require('react');
const ReactDom = require('react-dom');
const { hot } = require('react-hot-loader/root');
const WordRelay = require('./WordRelay');
const Hot = hot(WordRelay);
ReactDom.render(<Hot />, document.querySelector('#root'));
5. webpack.config.js의 plugins와 output 수정
// 부분 생략
module.exports = {
module: {
rules: [{
test: ,
loader: '',
options: {
presets: [],
plugins: [
'react-hot-loader/babel'
],
},
}],
},
output: {
// 실제 경로
path: path.join(__dirname, 'dist'),
filename: 'app.js',
// 가상 경로
// nodejs의 app.use('/dist', express.static(__dirname, 'dist'))와 유사
publicPath: '/dist/'
},
};
TMI ! webpack.config.js를 수정하면 server를 종료했다가 다시 실행시켜 주어야 한다.
2-10. 끝말잇기 Hooks로 전환하기
· 브라우저 콘솔 [HMR]와 [WDS]
이전에 자동 빌드를 위해 설치한 모듈에서 브라우저 콘솔 창에 여러 정보를 나타낸다.
[HMR] Hot Module Reload
[WDS] Web Dev Server
'기타 🎸 > 강의' 카테고리의 다른 글
[미운코딩새끼] 4시간 만에 끝내는 파이썬 기초 (0) | 2019.12.27 |
---|---|
[React 기본 강좌] 1. 리액트란 무엇인가? 왜 쓰는가? (0) | 2019.12.14 |
[React로 NodeBird SNS 만들기] 1. Hello, Next.js (0) | 2019.12.09 |
- Total
- Today
- Yesterday
- nodebird
- Error
- OnClickListener
- 정보전산직
- 템플릿
- 미운코딩새끼
- 줌바 댄스
- nodejs
- github desktop
- power mode
- python
- Inkscape
- 일상
- Live Server
- EJS
- Spinner
- Github Pages
- 강의
- vscode
- react
- user setting
- 줌사모
- flutter_form_builder
- Maker League
- 레이저 커팅
- github
- 프로젝트 업로드
- intro 화면
- activiry
- Android
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |