React #5 create-react-app
by JiwonDevreact ํ๋ก์ ํธ๋ฅผ ์์ฑํด๋ด ์๋ค.
์ฝ์์ฐฝ์ npx create-react-app ์ ์ ๋ ฅํ๊ฑฐ๋ ํธ์ง๊ธฐ์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
create-react-app.dev/docs/getting-started
Getting Started | Create React App
Create React App is an officially supported way to create single-page React
create-react-app.dev
์ฐธ๊ณ ๋ก ์ด ๋ฐฉ์์ผ๋ก ์ค์นํ๊ฒ ๋๋ฉด yarn ํ๋ก์ ํธ ๋งค๋์ ๊ฐ ํจ๊ป ์ค์น๋ฉ๋๋ค.
yarn์ ํ์ด์ค๋ถ์์ npm์ฒ๋ผ ์ฌ์ฉํ ๋ ค๊ณ ๋ง๋ ์์กด์ฑ ๊ด๋ฆฌ ํ๋ก์ ํธ ๋งค๋์ ์ธ๋ฐ
npm์ ๋จ์ ์ธ ํจํค์ง ์ค์น ์๋์ ๋ณด์์ฑ์ ๊ฐ์ ํ ๋ ค๊ณ ๋ง๋ ๋๊ตฌ์ ๋๋ค.
๋ ์ค ๋ญ๊ฐ ๋ ์ข๋ค๊ธฐ๋ณด๋ค๋ ๋ ๋ค ์ฅ๋จ์ ์ด ์์ต๋๋ค.
์ฌ์ฉ๋ฒ์ npm๊ณผ ๋น์ทํฉ๋๋ค.
npm install -g yarn yarn start |
ํ๋ก์ ํธ๋ฅผ ์์ฑ ์๋ฃํ๋ค๋ฉด ์๋์ ๊ฐ์ ๊ตฌ์กฐ๊ฐ ์์ฑ๋ฉ๋๋ค.
๊ฐ๋จํ๊ฒ ์ถ๊ฐ๋ ํ์ผ์ ์ค๋ช ํ์๋ฉด
manifest.json : ์ฑ์ ๋ํ ๊ธฐ๋ณธ ์ ๋ณด๋ฅผ ๋ด์ ํ์ผ์ ๋๋ค. ๋ฐฐ๊ฒฝ์, ์ฑ์ ์ด๋ฆ, ํ์คํฌ๋ฆฐ ์์ด์ฝ๋ฑ์ ์ ๋ณด๋ฅผ ์ ์ฅํฉ๋๋ค.
index.js : ํด๋น ํ๋ก์ ํธ์ ์ง์ ์ ์ ๋๋ค. ์ฌ๊ธฐ์ render ์ฝ๋๋ฅผ ์์ฑํ๊ฒ ๋ฉ๋๋ค.
App.css, Index.css : cssํ์ผ์ด ํจ๊ป ์์ฑ๋์์ต๋๋ค.
ํ๋ก์ ํธ์ด๋ฆ.iml : node.js์ ์ค์ ํ์ผ์ ๋๋ค.
yarn.lock : yarn์ ์ค์ ํ์ผ์ ๋๋ค.
reportWebVitals.js : ๋ฆฌ์กํธ๋ ๊ด๋ จ์ ์๊ณ , ์น ํ์ด์ง์ ์ํ์ ๋ก๊ทธ๋ฅผ ํ์ธํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค.
์ฐธ๊ณ ๋ก ์ด์ ๋ฆฌ์กํธ๋ฒ์ ์์๋ serviceWorker.js ๋ผ๊ณ ๋ถ๋ ธ์ต๋๋ค.
setupTests.js : ๋ฆฌ์กํธ ํ ์คํธ ์ฝ๋ ์์ฑ์ฉ. ๋์ค์ ํ๋ก์ ํธ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ ๋ ๋ฐฐ์ฐ๊ฒ ๋ฉ๋๋ค.
#1 ์ปดํฌ๋ํธ ์์ฑ
ํ๋ก์ ํธ src ํด๋์์ components ํด๋๋ฅผ ๋ง๋ค๊ณ ํ๋์ฉ ์ถ๊ฐํด๋ด ์๋ค.
์ฐธ๊ณ ๋ก hot-loader ํ๋ฌ๊ทธ์ธ๋ ํจ๊ป ์ค์น๋์๋ค๋ฉด ํ๋ก์ ํธ๋ฅผ ์ฌ์์ํ์ง ์์๋ ์๋์ผ๋ก ์์ ๋ณธ์ด ๋ฐ์๋ฉ๋๋ค.
// index.js , ๊ธฐ๋ณธ ์์ฑ๋ ํ์ผ์
๋๋ค. ํ๋ก์ ํธ์ ์์์ง์
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './Components/App';
import reportWebVitals from './reportWebVitals';
// React.StrictMdoe ๊ฐ์ฒด๋ ์ฑ ๋ด์ ์ ์ฌ์ ์ธ ๋ฌธ์ ๋ฅผ ์ก๋ ๋๊ตฌ์
๋๋ค.
// ์ปดํฌ๋ํธ์ ์๋ช
์ฃผ๊ธฐ, ์์ ์ฑ, ๊ถ์ฅ๋์ง์๋ ์ฌ์ฉ๋ฒ๋ฑ์ ์ ๊ฒํ๋ ๋๊ตฌ์ด๋ฉฐ
// ์ญ์ ํ์
๋ ์๊ด์ ์์ต๋๋ค. ๋ฌผ๋ก index.js ๋ง๊ณ ๋ค๋ฅธ ๊ณณ์๋ ์ฌ์ฉ ํ ์ ์๊ตฌ์.
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);Q
// ๋ก๊ทธ๋ฅผ ๋จ๊ธฐ๋ ๋ฉ์๋์
๋๋ค. ํ์์๋ค๋ฉด ์ง์๋ ๋ฉ๋๋ค.
// Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
// src/Components/App.js
import React from "react";
import Contact from "./Contact";
export default class App extends React.Component{
render() {
return(
<div>
<h1> Hello </h1>
<Contact/>
</div>
)
}
}
// src/Components/ContactInfo.js
import React from "react";
// export default๋ฌธ์ ์ด๋ ๊ฒ ํด๋์ค ์ ์ธ ์์ ์์ฑํด๋ ๋ฉ๋๋ค.
export default class ContactInfo extends React.Component{
render() {
return(
<div>
{this.props.contact.name}
{this.props.contact.phone}
</div>
)
}
}
import React from "react";
import ContactInfo from "./ContactInfo";
export default 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() {
// const mapToComponent = (contactData) => {
// return contactData.map((contac,index) => {
// return (<ContactInfo contact={contac} key={index}/>)
// })
// };
const mapToComponent = (data) =>
data.map( (contact, i) =>
<ContactInfo contact={contact} key={i}/>
)
return (
<div>
{/* ์์์ ๋ง๋ ๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ ์ปดํฌ๋ํธ ์์ฑ.*/}
{mapToComponent(this.state.contactData)}
</div>
)
}
}
#2. Contact ์ปดํฌ๋ํธ ์์
ํด๋น ์ฝ๋์์๋ *๋๋ณด๊ธฐ JS ์ Sort์ Filter๋ฅผ ์ฌ์ฉํฉ๋๋ค.
arr.sort( [compareFunction] )
ํด๋น ๋ฐฐ์ด์ ์ ๋์ฝ๋ ๊ธฐ์ค ์ค๋ฆ์ฐจ์ (๋๋ ์ฃผ์ด์ง ๋น๊ตํจ์)๋ก ์ ๋ ฌํฉ๋๋ค.
์
๋ ฅํ ๋ฐฐ์ด ์์ ์์ฒด๋ฅผ ๋ฐ๊ฟ๋๋ค.
var name = [ 'la', 'ql' , 'qkw' ]
name.sort()
var name = [ 'la', 'ql' , 'qkw' ]
name.sort()
arr.filter( callback )
arr.filter( (์์, ์ธ๋ฑ์ค, ๋ฐฐ์ด) )
ํด๋น ๋ฐฐ์ด์์ callback ํจ์๋ฅผ ์ ์ฉ ํ์ ๋ true๋ฅผ ๋ฐํํ๋ ์์๋ง ๋จ๊ฒจ ์๋ก์ด ๋ฐฐ์ด์ ๋ง๋ญ๋๋ค.
๊ธฐ์กด์ ๋ฐฐ์ด์ ์์ ํ์ง ์์ต๋๋ค.
// ์ ์ ๋ฐฐ์ด์์ 5์ ๋ฐฐ์์ธ ์ ์๋ง ๋ชจ์ผ๊ธฐ
var arr = [4, 15, 377, 395, 400, 1024, 3000];
var arr2 = arr.filter(function (n) {
return n % 5 == 0;
});
console.log(arr2); // [15, 395, 400, 3000]
Contact ์ปดํฌ๋ํธ๋ฅผ ์์ ํด์ ๊ฒ์์ฐฝ๊ณผ ๊ทธ ๊ฒ์์ฐฝ์ ์ ๋ณด๋ฅผ ์ ์ฅํ ๋ก์ปฌ state๋ฅผ ๋ง๋ค์ด ์ค์๋ค.
import React from "react";
import ContactInfo from "./ContactInfo";
export default class Contact extends React.Component {
constructor(props) {
super(props);
this.state = {
keyword: '', // ๊ฒ์ ํค์๋๋ฅผ ์ ์ฅํ 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'},
]
}
// ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ด์์ this ํค์๋๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ๋ฐ์ธ๋ ํด์ฃผ์์ต๋๋ค.
this.handleChange = this.handleChange.bind(this);
}
// ์ด๋ฒคํธ ํธ๋ค๋ฌ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ์ต๋๋ค. ์
๋ ฅ๊ฐ์ ์ค์๊ฐ์ผ๋ก state์ ์ ์ฅํฉ๋๋ค.
handleChange(e) {
this.setState({
keyword: e.target.value
})
}
render() {
const mapToComponent = (data) =>
data.map((contact, i) =>
<ContactInfo contact={contact} key={i}/>
)
return (
<div>
<h1>Contacts</h1>
<input type="text" name="keyword" placeholder="Search"
value={this.state.keyword} onChange={this.handleChange}/>
{/* ์์์ ๋ง๋ ๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ ์ปดํฌ๋ํธ ์์ฑ.*/}
{mapToComponent(this.state.contactData)}
</div>
)
}
}
๊ทธ๋ฆฌ๊ณ mapToComponent ๋ฉ์๋๋ฅผ ์์ ํ์ฌ ์ด๋ฆ ๊ฒ์๊ธฐ๋ฅ์ ์ถ๊ฐํด๋ด ์๋ค.
const mapToComponent = (data) =>
data.filter((contact)=>contact.name.toLowerCase().includes(this.state.keyword.toLowerCase()))
.map((contact, i) => <ContactInfo contact={contact} key={i}/>
)
'๐ผFront > React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋ฆฌ์กํธ์ Virtual DOM (0) | 2021.04.16 |
---|---|
React #4 ํ๋ก์ ํธ ์์ฑ ๋ฐ ์ปดํฌ๋ํธ์ ์ดํด (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