์๋์ ๊ฐ์ด key๊ฐ ๋ชจ๋ ""๋ก ์์ฑํด์ฃผ์ด์ผ ํ๋ค.
{
"data": [{
"id": 101,
"category": "์ฝ๋ ๋ธ๋ฃจ",
"name": "์์ด์คํฌ๋ฆผ ๋ธ๋ ๋ฉ ์ฝ๋ ๋ธ๋ฃจ",
"engName": "Ice Cream Blending Cold Brew",
"summary": "",
"desc": "",
"imgUrl": "",
"servingSize": "Tall(ํจ) / 355ml (12 fl oz)",
"kcal": "420",
"fat": "6",
"protein": "53",
"natrium": "140",
"sugars": "53",
"caffeine": "210",
"allergen": "๋๋ / ์ฐ์ "
},
{
"id": 102,
"category": "์ฝ๋ ๋ธ๋ฃจ",
"name": "๋์ดํธ๋ก ๋ฐ๋๋ผ ํฌ๋ฆผ",
"engName": "Nitro Vanilla Cream",
"summary": "",
"desc": "",
"imgUrl": "",
"servingSize": "Tall(ํจ) / 355ml (12 fl oz)",
"kcal": "75",
"fat": "2",
"protein": "1",
"natrium": "20",
"sugars": "10",
"caffeine": "245",
"allergen": "์ฐ์ "
}
]
}
fetch()ํจ์์์ default ๋ฉ์๋๋ GET์ด๋ค.
constructor() {
super();
this.state = {
products: [],
}
}
componentDidMount() {
fetch('http://localhost:3000/data/myData.json', { method: 'GET'
})
.then(res => res.json())
.then(data => {
this.setState({
products: data.data,
});
});
}
json ๋ฐ์ดํฐ์ 'data'๋ฅผ products์ ๋ด์๊ธฐ ๋๋ฌธ์ products ๋ฐฐ์ด์๋ [{id:101, ...}, {id:102, ...}]๊ฐ ๋ด๊ธฐ๊ฒ ๋๊ณ , renderํจ์ ์์์ {this.state.producs}๋ก ์ ๊ทผํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
์ฒซ ๋ฒ์งธ then ํจ์์ ์ ๋ฌ๋ ์ธ์ res๋ http ํต์ ์์ฒญ๊ณผ ์๋ต์์ ์๋ต์ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ ๊ฐ์ฒด(Response Object)๊ณ , ์ด ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ json ํจ์๋ฅผ ํธ์ถํ๊ณ return ํด์ผ ํ๋ค. ์ดํ ๋ ๋ฒ์งธ then์์ ์๋ต body์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ์ ์๊ฒ ๋๋ค.
๋ฐฑ์๋์์ ์๋ต body๋ฅผ ์ฃผ์ง ์๋ ๊ฒฝ์ฐ๋ ์๋ค. ์ด ๋ json()์ ํธ์ถํ๋ฉด ์๋ฌ๊ฐ ๋๋ค. ์ด ๊ฒฝ์ฐ res.status๋ก ์๋ต ์ฝ๋๋ฅผ ํ์ธํ๊ณ (200, 403 ๋ฑ) then ์์์ if๋ฌธ์ ์ฌ์ฉํด body๋ฅผ ๋ฐ์ ๊ฒฝ์ฐ์ ๋ฐ์ง ์์ ๊ฒฝ์ฐ๋ก ๋๋์ด returnํ๋ฉด ๋๋ค.
ํ ๊ฐ์ง ์๋ฌธ, fetch๋ ํญ์ componentDidMount์์ ํด์ผ ํ ๊น?
๋ฆฌ์กํธ๋ ํ๋ก ํธ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๊ธฐ ๋๋ฌธ์ ๋
ธ๋๋ ์คํ๋ง ๊ฐ์ ์๋ฒ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ฅผ ์ด์ฉํด ๋ง๋ค์ด์ง ์น์๋ฒ์ ํต์ ํ๋ ๋ฐฉ๋ฒ์ผ๋ก ๊ตฌํ๋๋ค. ์๋ฒ์ API๋ฅผ ํธ์ถํ๊ธฐ ์ํด Life cycle์ ์ดํดํด๋ณด์.
//์์ฑ ๋ ๋
constructor()
componentWillMount()
render()
componentDidMount()
//update
shouldComponentUpdate()
- ์ปดํฌ๋ํธ์ ๋ฐ์ดํฐ์ ํ๋ฉด์ ์ถ๋ ฅ๋ ๋ด์ฉ์ด ๋ค๋ฅผ ๋ ๋์, ๊ธฐ๋ณธ์ ์ผ๋ก true ๋ฐํ
componentWillUpdate()
render()
componentDidUpdate()
- ํ๋ฉด์ ์ถ๋ ฅ๋๋ ํ๋ฉด ๊ตฌ์ฑ์ ๋ณ๊ฒฝํ๊ณ ์ ํ ๋ ๋ง์ด ์ฌ์ฉ
//์ปดํฌ๋ํธ ํด์
componentWillUnmount()
- ์ปดํฌ๋ํธ์ ๋์์ ์ํด ์ฌ์ฉ๋์๋ ๋ฉ์๋๋ค์ ๋ฆฌ์์ค๋ฅผ ์ ๊ฑฐ
- ์ดํ๋ฆฌ์ผ์ด์
์ฑ๋ฅ ํฅ์์ ์ํด ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ ํจ์
componentDidMount์์ API๋ฅผ ํธ์ถํ๋ฉด ํจ๊ณผ์ ์ด๋ค.
์๊ทธ๋ด๊น? componentDidMount๋ ์ปดํฌ๋ํธ๊ฐ ์์ฑ๋ ๋ ํ ๋ฒ๋ง ๋ฐ์ํ๋ค. props๋ state๊ฐ ๋ฐ๋๋ ๋ฑ ๋ณํ๊ฐ ์๊ธฐ๋ฉด componentDidUpdate๊ฐ ๊ณ์ ๋ถ๋ฆฌ๊ฒ ๋๋๋ฐ, ๊ทธ๋ ๊ฒ ๋๋ฉด ๋ณํ๊ฐ ์๋ ๋ฐ์ดํฐ๋ ๊ณ์ ๋ค์ ๋ถ๋ฌ์์ผํ๋๊น ํ์์๋ ์ผ์ ํ๋ ๊ฒ์ด ๋๋ค. ๋ฐ๋ผ์ componentDidMount์์ ํ๋ ๊ฒ์ด ์ ๋ฆฌํ ๊ฒ ๊ฐ๋ค.
constructor ํจ์๋ ์์ฑ๋ ๋๋ง ํธ์ถ๋๋ค. ์ฌ๊ธฐ์ API๋ฅผ ํธ์ถํ๋ ๊ฒ์๋ ์ด๋ค ๋ฌธ์ ๊ฐ ์์๊น? ๋ฆฌ์กํธ ๋ผ์ดํ ์ฌ์ดํด์์ render ์ดํ DOM์ ์ ๋ฐ์ดํธ ์ํ๊ฐ ๋๋ค. ๋ง์ฝ constructor์์ API๋ฅผ ํธ์ถํ๊ฒ ๋๋ฉด ๋ฐ์ดํฐ๋ fetch๊ฐ ๋๊ฒ ์ง๋ง, ์ปดํฌ๋ํธ๋ DOM์ ์์ง ์กด์ฌํ๋ ์ํ๊ฐ ์๋๊ฒ ๋๋ค. ๋ฐ๋ผ์ DOM์ด ์ ๋ฐ์ดํธ ๋ ์ํ์์ fetch ํจ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ ๊ฒ ๊ฐ๋ค.
user Id๊ฐ props๋ฅผ ํตํด ๋์ด์จ๋ค๊ณ ๊ฐ์ ํ๋ฉด ์๋์ ๊ฐ์ด fetch๋ฌธ ์์์ ์ฌ์ฉํ ์ ์๋ค.
class User extends Component {
componentDidMount() {
const { userId } = this.props;
fetch(`https://api.google.com/user/${userId}`)
.then(res => res.json())
.then(res => {
if (res.success) {
console.log(`${res.user.name}` ๋ ํ์ํฉ๋๋ค);
}
});
}
}
GET ๋ฉ์๋ ๋ง๊ณ POST ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ผ ํ ๋๋ ์ ๋ฌํด์ผ ํ ๋ฉ์ธ์ง๊ฐ ์กฐ๊ธ ๋ ๊ธธ์ด์ง๋ค. ์ ๋ฌํ ๋ฐ์ดํฐ๋ฅผ body์ ์์ฑํ๋๋ฐ JSON ํํ๋ก ์ ๋ฌ๋์ด์ผ ํ๋ stringify๋ก JSON ํ์์ ๋ง๊ฒ ๋ฐ๊พธ์ด ์ค๋ค.
fetch('https://api.google.com/user', {
method: 'post',
body: JSON.stringify({
name: "dabin",
batch: 1
})
})
.then(res => res.json())
.then(res => {
if (res.success) {
alert("์ ์ฅ ์๋ฃ");
}
})
์๋ฒ ์ค ๋ํ ์ผ ํ์ด์ง์ ๊ฐ ์ปคํผ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ธฐ ์ํด ์ฌ์ฉํ fetch ํจ์์๋ this.props.match.params.id๋ฅผ ์ฌ์ฉํ๋ค.
<Route
exact
path="/list-dabin/detail-dabin/:id"
component={detailDabin}
/>
๊ฒฝ๋ก๋ฅผ :id๋ก ๋ฐ์ดํฐ์ id๊ฐ์ ๋ฐ๋ผ ๋ณํ๋๋ก ๋ง๋ค์๊ณ , ์ด id๊ฐ์ด JSON ๋ฐ์ดํฐ์ id๊ฐ์ด ์ผ์นํ ๋ ๊ทธ ๊ฐ์ฒด๋ง ํ๋ ๋ค๊ณ ์ค๋๋ก ๋ง๋ค์ด์ ์ปคํผ๋ณ ์์ธํ์ด์ง๋ฅผ ๊ตฌํํ๋ค.
constructor() {
super();
this.state = {
details: {},
};
}
componentDidMount() {
const id = this.props.match.params.id * 1;
console.log(id);
fetch('http://localhost:3000/data/detailMockData.json', {
method: 'GET',
})
.then(res => res.json())
.then(data => {
this.setState({
details: data.data.filter(detail => detail.id === id)[0],
});
});
}
fetch๋ก ๋ฐ์์จ ๋ฐ์ดํฐ๋ฅผ map ํ๋ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์๋๋ฐ, ๋ง์ฝ ์ค๋ฅ๊ฐ ๋์ ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค์ง ๋ชปํ์ ๋๋ฅผ ์ํด ์ด๋ป๊ฒ ํ ์ ์์๊น? ๋ง์ฝ ๋ฐ์ดํฐ๊ฐ undefined๋ผ๋ฉด ์ฝ๋๋ฅผ ์คํํ์ง ์๋๋ก ์์ธ์ฒ๋ฆฌ๋ฅผ ํด๋๋ ๊ฒ์ด๋ค. ๋ค์ํ ๋ฐฉ์์ด ์๋๋ฐ, ์๋ฅผ ๋ค๋ฉด if๋ฌธ์ ์ฌ์ฉํ๋ค๊ฑฐ๋ optional chaining(?.)์ ์ฌ์ฉํ๋ฉด ๋๋ค
optional chaining ์ฐ์ฐ์
?. ์ฐ๊ฒฐ๋ ๊ฐ์ฒด ์ฒด์ธ ๋ด์ ๊น์์ด ์์นํ ์์ฑ ๊ฐ์ ์ฝ์ ์ ์๋ค. ๋ง์ฝ ์ฐธ์กฐ๊ฐ null ๋๋ undefined๋ผ๋ฉด, ์๋ฌ๊ฐ ๋ฐ์ํ๋ ๊ฒ ๋์ ํํ์์ ๋ฆฌํด ๊ฐ์ undefined๊ฐ ๋๋ค.
์ฐธ์กฐ๊ฐ ๋๋ฝ๋ ๊ฐ๋ฅ์ฑ์ด ์๋ ๊ฒฝ์ฐ, ์ด๋ค ์์ฑ์ด ํ์ํ์ง ๋ณด์ฆ์ด ํ์คํ์ง ์์ ๊ฒฝ์ฐ ์งง๊ณ ๊ฐ๋จํ ํํ์์ผ๋ก ๊ฐ์ฒด์ ๋ด์ฉ์ ํ์ํ ์ ์๋ค.const customer = { name: 'dabin', laptop: { name: 'macBook' } }; const keyboardName = adventurer.keyboard?.name; console.log(keyboardName); //undefined.