React #4 ํ๋ก์ ํธ ์์ฑ ๋ฐ ์ปดํฌ๋ํธ์ ์ดํด
by JiwonDev๋ฆฌ์กํธ๋ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ View ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก
ํน๋ณํ ๋ฌธ๋ฒ ๊ณต๋ถ ์์ด ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์๋ค๋ฉด ์ ์ฌํ๊ฒ ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.
์ฃผ๋ก ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก ๋ง์ด ์์ฑํ๊ฒ ๋ฉ๋๋ค.
์ด ๊ธ์์๋ ์๋ฐ์คํฌ๋ฆฝํธ์ *๋๋ณด๊ธฐ arr.map(callback, [thisArg]) ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
arr.map(callback, [thisArg])
Array.prototype.map( )
callback ํจ์๋ฅผ ์ฃผ๋ฉด, ๋ฐฐ์ด์ ์์๋ฅผ ์ํํ๋ฉฐ ํด๋น ํจ์ ์ ์ฉ ์ํจ ๋ฐฐ์ด์ ๋ฐํํฉ๋๋ค.
๋จ, ์๋ณธ ๋ฐฐ์ด์ ์์ ํ์ง ์์ต๋๋ค.
[thisArg]๋ฅผ ์ ๋ ฅํ๋ค๋ฉด ์ฝ๋ฐฑํจ์ ๋ด๋ถ์์ ์ฌ์ฉํ this ๊ฐ์ ์ค์ ํด ์ค์ ์์ต๋๋ค.
์ฝ๋ฐฑ ํจ์
callback ( currentValue, [index ,[array]] )
currentValue๋ ํ์ฌ ์ฒ๋ฆฌ ์ค์ธ ์์, index๋ ์ฒ๋ฆฌ ์ค์ธ ์์์ ์ธ๋ฑ์ค, array๋ ์ ์ฒด ๋ฐฐ์ด ๊ฐ์ ๋๋ค.
๋ณดํต ์ฝ๋ฐฑํจ์๋ ํ์ดํ ํจ์๋ก ๋ง์ด ์์ฑํฉ๋๋ค.
let numbers [ 1,2,3,4,5 ];
let myCallback = fucntion(num,index){
return num+index;
}
// ์๋ 2๊ฐ์ ๋ฐฐ์ด์ ๊ฒฐ๊ณผ ๊ฐ์ ๊ฐ์ต๋๋ค.
let newNumbers1 = number.map(myCallback);
let newNumbers2 = numbers.map( (num,index) => num+inedx );
#1. ์ปดํฌ๋ํธ ๊ตฌ์กฐํ
๋ฆฌ์กํธ๋ ์ปดํฌ๋ํธ ๋จ์๋ก view๋ฅผ ๊ตฌ์ฑํฉ๋๋ค.
class Contact extends React.Component {
render() {
return (
<div>
<div>Jiwo1 010-9999-9991</div>
<div>Jiwo2 010-9999-9992</div>
<div>Jiwo3 010-9999-9993</div>
<div>Jiwo4 010-9999-9994</div>
</div>
)
}
}
์ ์ฝ๋๋ฅผ ์ปดํฌ๋ํธ๋ก ๊ฐ์ฒดํ ์ํค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋ง๋ค ์ ์์ต๋๋ค.
class ContactInfo extends React.Component {
// ContactInfo๋ฅผ ๊ฐ์ฒดํ ์์ผฐ์ต๋๋ค.
render() {
return (
<div>
{this.props.contact.name}
{this.props.contact.phone}
</div>
);
}
}
class Contact extends React.Component {
constructor(props) {
super(props);
this.state={
// ๋ฐ์ดํฐ๋ฅผ [๊ฐ์ฒด, ๊ฐ์ฒด...] ํํ๋ก state์ ๋ฑ๋กํ์์ต๋๋ค.
contactData:[
{name:'Jiwo1',phone:'010-9999-9991'},
{name:'Jiwo2',phone:'010-9999-9992'},
{name:'Jiwo3',phone:'010-9999-9993'},
{name:'Jiwo4',phone:'010-9999-9994'},
]
}
}
render() {
/* ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ๊ธฐ๋ฒ์ ์ฌ์ฉํ์ฌ contactData๋ฅผ ๋ฐ์ผ๋ฉด
<ContactInfo/> ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ๋ฉ์๋๋ฅผ ๋ง๋ญ๋๋ค.
์ฐธ๊ณ ๋ก ์ด๋ฐ์์ผ๋ก ๊ฐ์ ๊ฐ์ฒด๋ฅผ ์ฌ๋ฌ๊ฐ ์์ฑํ ๋ ๊ฐ์ฒด๋ณ๋ก key๊ฐ์ ๋ฐ๋ก ์ฃผ์ง ์์ผ๋ฉด
๋ฆฌ์กํธ ์์ฒด์์ ๊ฒฝ๊ณ ๋ฅผ ๋์ฐ๋ key={index}๋ก ๊ฐ๋จํ๊ฒ ์ธ๋ฑ์ค๊ฐ์ ํค๋ก ์ค์๋ค.
*/
const mapToComponent = (contactData) => {
return contactData.map((contac,index) => {
return (<ContactInfo contact={contac} key={index}/>)
})
};
return (
<div>
// ์์์ ๋ง๋ ๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ ์ปดํฌ๋ํธ ์์ฑ.
{mapToComponent(this.state.contactData)}
</div>
)
}
}
#2. ํ๋ก์ ํธ ์์ฑ
์ฐ์ , ๋ธ๋ผ์ฐ์ ๋ฐ์์๋ ์ฌ์ฉํ ์ ์๊ฒ ์๋ฐ์คํฌ๋ฆฝํธ ๋ฐํ์ Node.js๋ฅผ ์ค์นํด์ค๋๋ค.
Node.js
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.
nodejs.org
๊ทธ๋ฆฌ๊ณ Node.js์์ ์ ๊ณตํ๋ npm(node Package Manager)์ ํตํด ํ์ฌ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ webpack๋ ์ค์นํด์ค์๋ค.
npm install --global webpack webpack-dev-server |
--global (๋๋ -g) : ํด๋น ์ปดํจํฐ์ ๋ชจ๋ ํ๋ก์ ํธ๊ฐ ์ฌ์ฉํ ์ ์๊ฒ ์ค์นํฉ๋๋ค.
webpack : ๋ธ๋ผ์ฐ์ ์์์ import๋ฅผ ํ ์ ์๊ฒ ํด์ฃผ๊ณ , .jsํ์ผ๋ค์ ํ๋๋ก ๊ตฌ์กฐํ ์์ผ์ค๋๋ค.
webpack-dev-server : ๋ณ๋์ ์๋ฒ ์์ด๋ static ํ์ผ์ ๋ค๋ฃจ๋ ์น ์๋ฒ๋ฅผ ์ด ์ ์๊ฒ ํด์ฃผ๋ฉฐ ์ฝ๋๊ฐ ์์ ๋ ๋ ๋ง๋ค ์๋์ผ๋ก ๋ฆฌ๋ก๋ ๋๊ฒ ํ ์ ์์ต๋๋ค(hot-loader ๊ธฐ๋ฅ)
npm init ๋ฅผ ์ ๋ ฅํ๋ฉด node.js์ ๊ธฐ๋ณธ ์ค์ ํ์ผ(package.json ๋ฑ)์ด ์์ฑ๋ฉ๋๋ค.
๋๋ ์ฌ์ฉํ์๋ IDE ํธ์ง๊ธฐ์ ๊ธฐ๋ฅ์ ํตํด ๋ ธ๋ ํ๋ก์ ํธ๋ฅผ ์์ฑํ์ ๋ ๋ฉ๋๋ค.
(์ฐธ๊ณ ๋ก npx create-react-app ๋ช ๋ น์ด๋ฅผ ํตํด ์๋์ ๊ณผ์ ์ ํฌํจํ ๊ธฐ๋ณธ ํ๋ก์ ํธ๋ฅผ ์์ฑ ํ ์ ์์ต๋๋ค.)
๊ทธ๋ฆฌ๊ณ react ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ฐํ์(react-dom)์ ์ค์นํด์ค์๋ค.
์ฐธ๊ณ ๋ก --save๋ ํ์ฌ ํ๋ก์ ํธ์ node ์ค์ ํ์ผ(package.json)์ ์ค์น๋ด์ฉ์ ์ ์ฅํ๋ ๋ช ๋ น์ด์ ๋๋ค.
npm install --save react react-dom |
๋ฆฌ์กํธ JSX ๋ฌธ๋ฒ๊ณผ webpack์ ์ฌ์ฉํ๊ธฐ์ํด์ ์๋์ ๋ฆฌ์กํธ ๊ฐ๋ฐ ์์กด ๋ชจ๋๋ ์ค์นํด์ค์๋ค.
--save-dev๋ --save์ ๋์ผํ์ง๋ง, ํ์ฌ ํ๋ก์ ํธ ๊ฐ๋ฐ์ฉ์ผ๋ก ์ค์นํ์ฌ ๋์ค์ ํจํค์ง ๊ด๋ฆฌ๋ฅผ ํธํ๊ฒ ํด์ค๋๋ค.
npm install --save-dev babel-core bable-loader babel-preset-es2015 babel-preset-react npm install --save-dev react-hot-loader webpack webpack-dev-server |
๊ทธ๋ฆฌ๊ณ package.json ์ ๋ค์ด๊ฐ sciprts๋ฅผ ์ถ๊ฐํด์ค๋๋ค.
...
"script" : {
"test" : "..."
"dev-server" : "webpack-dev-server"
}
์ด๋ ๊ฒ ํด์ฃผ๋ฉด ์์ผ๋ก npm run dev-server ๋ช ๋ น์ด๋ฅผ ํตํด ์ฐ๋ฆฌ ํ๋ก์ ํธ๋ฅผ ์คํ ์ํฌ ์ ์์ต๋๋ค.
#2-1 Webpack ์ค์
node๋ก ๊ฐ๋ฐ์ ํ์ํ ํจํค์ง๋ค์ ๋ชจ๋ ์ค์นํ๋ค๋ฉด, Webpack ์ค์ ํ์ผ์ ๋ง๋ค์ด์ค์๋ค. ๋ณต์ฌํด์ ์์ฑํ๋ฉด ๋ฉ๋๋ค.
/webpack.config.js
var webpack = require('webpack');
module.exports = {
entry: './src/index.js',
output: {
path: __dirname + '/public/',
filename: 'bundle.js'
},
devServer: {
hot: true,
inline: true,
host: '0.0.0.0',
port: 4000,
contentBase: __dirname + '/public/',
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/,
query: {
cacheDirectory: true,
presets: ['es2015', 'react']
}
}
]
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
}
์ฐธ๊ณ ๋ก ์ ์ฝ๋์ ์ค๋ช ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
// ES5 ์๋ฐ์คํฌ๋ฆฝํธ ๋ด์ฅํจ์ (ES6๋ถํฐ๋ import)
var require = function(src){ //line 1 ์ธ์๋ฅผ ๋ฐ์์์
var fileAsStr = readFile(src) //line 2 ํด๋น ์ฝ๋๋ฅผ ๋ถ๋ฌ์จ ํ
var module.exports = {} //line 3 exports ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ณ
eval(fileAsStr) //line 4 ์์ค๋ฅผ ๋ณต์ฌํฉ๋๋ค. exports์ key:value๋ก ์ฑ์์ง๋๋ค.
return module.exports //line 5 ์์ฑ๋ exports๋ฅผ ๋ฐํํฉ๋๋ค.
}
// npm ์ค์นํ webpack ์ฝ๋๋ฅผ require (ES6์ดํ์์๋ import ํค์๋)๋ก ๋ถ๋ฌ์ต๋๋ค.
// require ํจ์๋ ํด๋น ์ฝ๋๋ด์ module.exports๋ฅผ ๋ฆฌํดํฉ๋๋ค.
var webpack = require('webpack');
// ๋ค๋ฅธ ์ธ๋ถ ์๋ฐ์คํฌ๋ฆฝํธ์์ ์ฌ์ฉํ ์ ์๋๋ก exports๋ฅผ ๋ฑ๋กํฉ๋๋ค.
// ์ฐธ๊ณ ๋ก module.exports ์ exports ํค์๋๋ ๋์ผํ ๊ธฐ๋ฅ์ ํฉ๋๋ค.
module.exports = {
entry: './src/index.js',
// entry์ ํ์ํ ๋ชจ๋๋ค์ ๋ถ๋ฌ์ต๋๋ค. ์ฌ๋ฌ๊ฐ๋ผ๋ฉด [ a, b... ]
output: { // ํฉ์น ๋ชจ๋ ํ์ผ๋ค์ ์ ์ฅํ ๊ฒฝ๋ก
path: __dirname + '/public/',
filename: 'bundle.js'
},
devServer: { // ๊ฐ๋ฐ์ฉ Server ์ค์ ์
๋๋ค.
hot: true, // hot-loader ์จ์คํ
inline: true, // hot-loader์ ํด๋ผ์ด์ธํธ๋ฅผ ๋ฒ๋ค์ ๊ฐ์ด ๋ฃ์ด์ค
host: '0.0.0.0', // ๊ธฐ๋ณธ๊ฐ์ localhost, ์ฌ์ฉํ๋ ํด๋ผ์ฐ๋์ ๋ฐ๋ผ ์ค์
port: 4000, // ํฌํธ ๋ณดํต 3000,4000
contentBase: __dirname + '/public/', //์ ์ ์ธ Content๋ฅผ ์ ์ฅํ ํด๋. ๊ธฐ๋ณธ์ Public
},
module: { //babel ์ค์
loaders: [ // ์ปดํ์ผ ์ด ์ธ์๋ less, sass, HTML-mini ๋ฑ ์ฌ๋ฌ๊ฐ์ง ์ค์ ๊ฐ๋ฅ.
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/,
query: {
cacheDirectory: true,
presets: ['es2015', 'react']
}
}
]
},
plugins: [ // webpack-hot-loader๋ ํ๋ฌ๊ทธ์ธ์
๋๋ค. ์ฌ๊ธฐ์ ์ถ๊ฐ
new webpack.HotModuleReplacementPlugin()
]
}
# 2-2 HTML ๋ฐ JS ์์ฑ
public ํด๋๋ฅผ ๋ง๋ค๊ณ , ํด๋น ํด๋์์ index.html์ ์์ฑํฉ๋๋ค.
์ฐธ๊ณ ๋ก public ํด๋์์๋ ์ด๋ฌํ ์ ์ ์ธ ๋ฐ์ดํฐ๊ฐ ๋ค์ด๊ฐ๋ฉฐ webpack์ ๊ด๋ฆฌ๋์์ ์ ์ธ๋ฉ๋๋ค.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React App</title>
</head>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
<!-- bundle.js ๋ Webpack์์ output์ผ๋ก ์ ๊ณตํ๋ ํ์ผ์
๋๋ค. -->
</body>
</html>
๊ทธ๋ฆฌ๊ณ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด ๋ด ์๋ค.
src/components/ ์ src/index.js ๋ฅผ ๋ง๋ค๋ฉด ๋ฉ๋๋ค. ์ฐ๋ฆฌ๊ฐ ๋ง๋ ์ปดํฌ๋ํธ๋ ํด๋น ํด๋์ ๋ชจ์๋๊ฒ๋๋ค.
webpack ์์ ES5๋ก ์ค์ ํ์์ผ๋ฏ๋ก ES6 ๋ฌธ๋ฒ์ ์ฌ์ฉํ ๋ ค๋ฉด ๋ฐ๋ก ์ค์ ์ ํด์ฃผ์ด์ผํฉ๋๋ค.
ํ๋ก์ ํธ ๋ฃจํธ ๋๋ ํ ๋ฆฌ์ .jshintrc ๋ฅผ ๋ง๋ค์ด ๋ค์ ์ฝ๋๋ฅผ ์ ๋ ฅํด์ค์๋ค.
{
"esversion" : 6
}
์ด ๊ณผ์ ์ ๋ง์ณค๋ค๋ฉด ํ๋ก์ ํธ ๊ตฌ์ฑ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๋๋ต์ ์ธ ํ๋ก์ ํธ์ ๊ตฌ์กฐ๋ฅผ ํ์ ํ๋ค๋ฉด, ๋ค์ ๊ธ์์๋ npx create-react-app ์ผ๋ก ๊ธฐ๋ณธ ํ๋ก์ ํธ ํ(๋ณด์ผ๋ฌ ํ๋ ์ดํธ)๋ฅผ ์ด์ฉํ์ฌ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
'๐ผFront > React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋ฆฌ์กํธ์ Virtual DOM (0) | 2021.04.16 |
---|---|
React #5 create-react-app (0) | 2021.04.05 |
React #3 props & state (0) | 2021.04.05 |
React #2 ๋ฆฌ์กํธ.JS (0) | 2021.04.05 |
React #1 ๊ฐ๋ (0) | 2021.03.29 |
๋ธ๋ก๊ทธ์ ์ ๋ณด
JiwonDev
JiwonDev