whatisthis?

220317 [TIL] Today I Learned ๐Ÿ’ฏ React.js ๋ณธ๋ฌธ

WEB STUDY/REACT

220317 [TIL] Today I Learned ๐Ÿ’ฏ React.js

thisisyjin 2022. 3. 17. 12:47

React.js

 

 

๐Ÿšฉ ๋ชฉ์ฐจ

 

ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ

ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ

- ๋ฐฐ์—ด ์ปดํฌ๋„ŒํŠธ

- ์ปดํฌ๋„ŒํŠธ์—์„œ์˜ ์ฝœ๋ฐฑ๊ณผ ์ด๋ฒคํŠธ๋ฆฌ์Šค๋„ˆ

 

 

 

 

 

ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ

 

์ƒ๋ช…์ฃผ๊ธฐ ๋ฉ”์†Œ๋“œ์™€ ์ปดํฌ๋„ŒํŠธ ๊ตฌ์„ฑ์š”์†Œ๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•˜๋Š” ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ.

 

์ด ๋‘๊ฐ€์ง€ ์ข…๋ฅ˜์˜ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉ.

 

- Component

- PureComponent

 

1 / Component ํด๋ž˜์Šค

- props, state, life-cycle method๊ฐ€ ๋“ค์–ด์žˆ๋Š” ๊ตฌ์กฐ์˜ ์ปดํฌ๋„ŒํŠธ

 

2 / PureComponenet ํด๋ž˜์Šค

- Component ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์€ ํด๋ž˜์Šค.

- shouldComponentUpdate() ํ•จ์ˆ˜๋ฅผ ์–•์€ ๋น„๊ต๋ฅผ ํ•˜๋„๋ก ์žฌ์ •์˜.

 

๐Ÿ“Œ shouldComponentUpdate(nextProps, nextState) 
 
ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ setState()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ state๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด
๋‹ค์‹œ ๋ Œ๋”๋งํ•ด์•ผํ•˜๋Š”์ง€ ํŒ๋‹จํ•˜๋Š” ํ•จ์ˆ˜.
 
์ฆ‰, ๋ฆฌ๋ Œ๋”๋ง ํ• ์ง€ ๋ง์ง€ ํŒ๋‹จ. ํ™”๋ฉด ๋ณ€๊ฒฝ์„ ์œ„ํ•œ ๊ฒ€์ฆ ์ž‘์—….
๋ฐ์ดํ„ฐ ๋ณ€ํ™”๋ฅผ ๋น„๊ตํ•˜๋Š” ์ž‘์—… ํฌํ•จ๋จ. (์„ฑ๋Šฅ์— ์˜ํ–ฅ ๅคš)

 

- ์–•์€ ๋น„๊ต๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ์—๋งŒ render()์„ ํ˜ธ์ถœํ•จ.

 

- ๐Ÿ“‚ reactjs.org/docs

React.PureComponent is similar to React.Component. 

The difference between them is that React.Component doesn’t implement shouldComponentUpdate(), 

but React.PureComponent implements it with a shallow prop and state comparison.

 

๐Ÿ™‹‍โ™‚๏ธ ์–•์€ ๋น„๊ต(shallowCompare) ๋ž€?

const list1 = [1, 2, 3, obj];
const list2 = [1, 2, 3, obj];

- ์–•์€ ๋น„๊ต์—์„œ list1๊ณผ list2๋Š” ๊ฐ™๋‹ค.
- cf. ๊นŠ์€ ๋น„๊ต (===)์—์„œ๋Š” list1๊ณผ list2๋Š” reference๊ฐ€ ๋‹ค๋ฅด๋ฏ€๋กœ ๋‹ค๋ฅด๋‹ค.

___


shallowCompare๋Š” ํ˜„์žฌ ์ƒํƒœ ๋ฐ nextState ๊ฐ์ฒด๋ฟ ์•„๋‹ˆ๋ผ
ํ˜„์žฌ props ๋ฐ nextProps ๊ฐ์ฒด์— ๋Œ€ํ•ด ์–•์€ ๋™๋“ฑ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์–•์€ ๋น„๊ต๋Š” ๋™๋“ฑ์„ฑ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
์Šค์นผ๋ผ ๊ฐ’ (์ˆซ์ž, ๋ฌธ์ž์—ด)์„ ๋น„๊ตํ•  ๋•Œ๋Š” ๊ฐ’์„ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.
๊ฐ์ฒด๋ฅผ ๋น„๊ตํ•  ๋•Œ ๊ฐ์ฒด์˜ ์†์„ฑ์„ ๋น„๊ตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฐธ์กฐ(Reference) ๋งŒ ๋น„๊ต๋ฉ๋‹ˆ๋‹ค. 
>> ๋™์ผํ•œ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š”์ง€.

- shallow compare ์—์„œ 
object๋“ค์€ ๋ ˆํผ๋Ÿฐ์Šค๋งŒ ์ฒดํฌํ•˜๊ธฐ๋•Œ๋ฌธ์— ๊ฐ™์€ ๊ฐ’์ด ๋“ค์–ด์žˆ๋Š” object์ด๋”๋ผ๋„ ํ•ญ์ƒ ๋‹ค๋ฅธ๊ฐ’์œผ๋กœ ์ฒดํฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

Component ํ•ญ์ƒ render()ํ•จ์ˆ˜ ํ˜ธ์ถœ
PureComponent ์–•์€ ๋น„๊ต๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ์—๋งŒ 
render() ํ˜ธ์ถœ

 

 โ• React.PureComponent๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ

1. state์™€ prop์ด immutable์ผ๋•Œ
( scalar ๊ฐ’๋“ค์€ shallow compare๋กœ ๊ฐ’์„ ๋น„๊ตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒ๊ด€์—†์ง€๋งŒ
object๋“ค์€ reference๋กœ ๋‹ค๋ฆ„์„ ์ฒดํฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ ์ ˆ์น˜ ๋ชปํ•˜๊ฒŒ ์‚ฌ์šฉ๋ ์ˆ˜ ์žˆ์Œ)

2. state์™€ prop์ด ๊ณ„์ธต(hierarchy) ํ˜น์€ ๋ณต์žกํ•œ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์„๋•Œ

3. shouldComponentUpdate lifecycle์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ณ„ํš์ผ๋•Œ

 

shallowCompare์„ ์œ„ํ•ด shallow-equal ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ shallowEqual() ํ•จ์ˆ˜๋ฅผ ์ด์šฉ.

 

import React from 'react';
import shallowEqual from 'shallow-equal';

export class PureComponent extends React.Component {
   shouldComponentUpdate(nextProps, nextState) {
      return !shallowEqual(this.props, nextProps) ||
             !shallowEqual(this.state, nextState)
      }
 }
 
 // ref๊ฐ€ ๋‹ฌ๋ผ๋„ ๊ฐ’์ด ๊ฐ™๋‹ค๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ, return (!true || !true)๊ฐ€ ๋จ
 // props๋ž‘ state ๋‘˜์ค‘ ํ•˜๋‚˜๋งŒ ์•ˆ๋ณ€ํ•ด๋„(์ฆ‰, ๊ฐ™์•„๋„) return false
 // shouldComponentUpdate()๊ฐ€ false๋ฅผ return ํ•˜๋ฏ€๋กœ render()๊ฐ€ ์‹คํ–‰ ์•ˆ๋จ!
 // โ• shouldComponentUpdate()๊ฐ€ true์—ฌ์•ผ ๋‹ค์Œ (life-cycle)๊ณผ์ •์ธ render()์„ ์ง„ํ–‰ํ•˜๋ฏ€๋กœ

 

 

โ–ช PureComponent ํด๋ž˜์Šค๋กœ ์„ ์–ธํ•œ ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š”

shouldComponentUpdate()์—์„œ shallowEqual()ํ•จ์ˆ˜๋กœ ์–•์€ ๋น„๊ต๋ฅผ ํ•˜์—ฌ

๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ์ด ์žˆ์œผ๋ฉด - ํ™”๋ฉด ์ƒˆ๋กœ ์ถœ๋ ฅ - render()ํ˜ธ์ถœํ•จ

๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ์ด ์—†์œผ๋ฉด - return false -  render()ํ˜ธ์ถœ ์•ˆํ•จ

 

โ–ช Component ํด๋ž˜์Šค๋กœ ์„ ์–ธํ•œ ์ปดํฌ๋„ŒํŠธ๋Š” ๋น„๊ต๊ณผ์ • ์—†์ด ํ•ญ์ƒ ์ƒˆ๋กœ ๋ Œ๋”๋งํ•จ.

(๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ์ด ์žˆ๋“  ๋ง๋“ ~)

 

 

 

 

๐Ÿš€

์•ฑ์˜ ์„ฑ๋Šฅ์„ ์ตœ๋Œ€ํ™” ํ•˜๊ธฐ ์œ„ํ•ด

PureComponent์™€ ๋ถˆ๋ณ€ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉ.

 

- ์˜ˆ> ์—์–ด๋น„์•ค๋น„์—์„œ

์ˆ™์†Œ ์ •๋ณด๊ฐ€ 10000๊ฐœ๊ฐ€ ์žˆ๋‹ค๋ฉด, 1๊ฐœ์˜ ์ •๋ณด๋งŒ ์ˆ˜์ •ํ–ˆ์„ ๋•Œ๋งˆ๋‹ค

9999๊ฐœ์˜ ์ˆ™์†Œ ์ •๋ณด๋ฅผ ๋น„๊ตํ•˜๋ฉด ๋น„ํšจ์œจ์ ์ž„.

 

- ์ •๋ณด๊ฐ€ ๋ฐ”๋€” ๋•Œ ๋งˆ๋‹ค ์ƒˆ ๋ฐฐ์—ด์„ ํ• ๋‹นํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ 

๋น„๊ต์†๋„๋ฅผ ์ตœ์ ํ™” ํ•  ์ˆ˜ ์žˆ์Œ

 

 

 

๐Ÿ”ป ์ฑ… ์˜ˆ์ œ ์ดํ•ด ์•ˆ๊ฐ€์„œ ํ˜ผ์ž ์ฃผ์ €๋ฆฌ ๐Ÿ“

๋”๋ณด๊ธฐ
ใ…‡

๋‹ต: 

MyComponent ์ƒˆ๋กœ๊ณ ์นจ

MyComponent ์ƒˆ๋กœ๊ณ ์นจ

MyPureComponent ์ƒˆ๋กœ๊ณ ์นจ

 

__

 

์ด๋ผ๊ณ  ํ•˜๋Š”๋ฐ, ์™œ ๊ทธ๋Ÿฐ์ง€ ๋ชจ๋ฅด๊ฒ ๋‹ค.

์ฒซ๋ฒˆ์งธ๋กœ setTimeout() ์ฒ˜์Œ๊บผ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด

this.listValue[0].name = 'Justin'; ์œผ๋กœ props๋ฅผ ์ˆ˜์ •ํ•œ๋‹ค.

 

์—ฌ๊ธฐ์„œ MyComponent๋Š” ๋ฌด์กฐ๊ฑด ๋ฆฌ๋ Œ๋”๋ง ํ•˜๋‹ˆ๊นŒ passํ•˜๊ณ 

MyPureComponent๋„ ์–•์€๋น„๊ต๋กœ ํ–ˆ์œผ๋‹ˆ props๊ฐ€ ๋ณ€ํ•œ ๊ฒƒ ์•„๋‹Œ๊ฐ€?

state๋„ ๋ณ€ํ•œ๊ฒƒ์ด๊ณ . 

 

๊ทผ๋ฐ ์ด๊ฒŒ ์•„๋งˆ props๋Š” ์•ˆ๋ณ€ํ•ด์„œ - return falseํ•ด์„œ - ๋ Œ๋”๋ง ์•ˆ๋จ

์ด๋ ‡๊ฒŒ ๊ตฌํ˜„์ด ๋˜์–ด์„œ ์ •๋‹ต์ด ์ €๋ ‡๊ฒŒ ๋œ ๊ฒƒ ๊ฐ™์€๋ฐ,

 

๋‚ด์ƒ๊ฐ์—” ... 

์ƒˆ๋กœ ๋ฐฐ์—ด์„ ํ• ๋‹นํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๊ณ ์„œ์•ผ listValue์˜ ์ฒซ๋ฒˆ์งธ ์š”์†Œ์˜ ๊ฐ’๋งŒ ๋ฐ”๋€๊ฑฐ๋‹ˆ๊นŒ

์–•์€ ๋น„๊ต๋กœ๋„ ์ €๊ฒŒ ์•ˆ๋ณ€ํ•œ๊ฑธ๋กœ ์น˜๋‚˜๋ณด๋‹ค. ์ฆ‰, 

 

 return !shallowEqual(this.props, nextProps) ||
             !shallowEqual(this.state, nextState)
      }

์ด๋ถ€๋ถ„์—์„œ this.props ๋ž‘ nextProps๊ฐ€ ๊ฐ™๋‹ค! Equal!๋กœ ํŒ๋ช…๋‚˜๊ณ 

this.state๋ž‘ nextState๋Š” ๊ฐ’์ด ํ™•์‹คํžˆ ๋‹ฌ๋ผ์กŒ์œผ๋ฏ€๋กœ Equal์ด ์•„๋‹ˆ๊ณ .

 

return !true ||  !false ํ•ด์„œ false๊ฐ€ ๋ฆฌํ„ด๋œ๋“ฏ. (state๋Š” ๋ณ€ํ–ˆ์–ด๋„ props๊ฐ€ ์•ˆ ๋ณ€ํ–ˆ์Œ)

๊ทธ๋ž˜์„œ ์ฒซ๋ฒˆ์งธ setTimeout์—์„  PureComponent๋Š” ๋ Œ๋”๋ง ์•ˆ๋œ๊ฒƒ.

 

์ฒ˜์Œ์—” ์ฒซ๋ฒˆ์งธ setTimeout์—์„œ

MyComponent ์ƒˆ๋กœ๊ณ ์นจ

MyPureComponent ์ƒˆ๋กœ๊ณ ์นจ

๊ฐ€ ๋‚˜์˜จ๋‹ค๊ณ  ์˜ˆ์ƒํ–ˆ๋‹ค.

 

์ด์ œ ๋‘๋ฒˆ์งธ setTimeout()์„ ๋ณด๋ฉด

this.listValue, ์ฆ‰ props๋ฅผ ์•„์˜ˆ ๋ฐฐ์—ดํ˜•ํƒœ๋กœ ์ƒˆ๋กœ ๋Œ€์ž… (=)์„ ํ•ด๋ฒ„๋ ธ์œผ๋‹ˆ

์ด๊ฑด ๊ฐ’์ด ๋ฐ”๋€๊ฑฐ๋ผ๊ณ  ๋ณด๋ฉด ๋œ๋‹ค.

 

์ด์ œ ๋ณด๋ฉด props๋„ ๋ณ€ํ•˜๊ณ , state๋„ ๋ณ€ํ–ˆ๋‹ค.

return !false || !false ํ•ด์„œ true๋ฅผ ๋ฆฌํ„ดํ•œ ๊ฒƒ.

 

 

 

 

๐Ÿ”‘ key point

 

this.listValue = [{name: 'Park'}, {name: 'Lee'}]; ์ผ๋•Œ,

 

1๏ธโƒฃ this.listValue[0].name = 'Justin';

- ๋ฐฐ์—ด ์•ˆ์— ๊ฐ์ฒด์˜ ์†์„ฑ๊ฐ’์ด ๋ฐ”๋€๊ฑฐ์ž„.

- ์ฆ‰, ๋ฐฐ์—ด(listValue)์ด ๋ฐ”๋€๊ฑด ์•„๋‹˜. ์–•์€ ๋น„๊ต๋ฅผ ํ•˜๋ฉด ์–˜๋Š” this.props = nextProps

 

2๏ธโƒฃ this.listValue = [{name: 'Justin'}, {name: 'Lee'}];

- ๋ฐฐ์—ด ์ž์ฒด๋ฅผ ๋Œ€์ž…(=)์œผ๋กœ ๋ฐ”๊ฟ”๋ฒ„๋ฆผ.

- ์•ˆ์— ๊ฐ’์€ ๊ฐ™์„์ง€ ๋ชฐ๋ผ๋„, listValue ์ž์ฒด๊ฐ€ ์ƒˆ๋กœ ์„ ์–ธ๋˜์—ˆ์œผ๋ฏ€๋กœ this.props != nextProps.

 

 

 

 

ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ

 

- state๊ฐ€ ์—†๋Š” ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ (SFC)

- React.StatelessComponent์ธ๋ฐ, ์ค„์—ฌ์„œ SFC๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ.

 

- state๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„ ์ถœ๋ ฅํ•  ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•จ.

๋ฐ์ดํ„ฐ(prop, context) => ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ => ์ถœ๋ ฅํ•  ์ปดํฌ๋„ŒํŠธ (JSX)

 

- state๊ฐ€ ์—†๊ณ , ํ”„๋กœํผํ‹ฐ์™€ ์ปจํ…์ŠคํŠธ๋งŒ์œผ๋กœ ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•˜๋ฏ€๋กœ ๋‹จ์ˆœํ•œ ๊ตฌ์กฐ์˜ UI ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ œ์ž‘ํ• ๋•Œ ์ฃผ๋กœ ์‚ฌ์šฉ.

- ์ƒ๋ช…์ฃผ๊ธฐ ํ•จ์ˆ˜๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ.

 

 

function TodaysPlanApp(props) {
  const { onButtonClick, hasPlan } = props;

  return (
    <div>
      {hasPlan ? <TodaysPlanApp /> : null}
      <button onClick={onButtonClick}>๊ณ„ํš ์—†์Œ</button>
    </div>
  );
}

export default TodaysPlanApp;

 

onButtonClick ํ•จ์ˆ˜์™€ hasPlan์„ props๋กœ ๋ฐ›๊ณ ,

hasPlan์ด true๋ฉด ๋ Œ๋”๋งํ•˜๊ณ , false๋ฉด ๋ Œ๋”๋งํ•˜์ง€ ์•Š์Œ.

 

 

 

 

๋ฐฐ์—ด ์ปดํฌ๋„ŒํŠธ

 

- ๊ฒŒ์‹œํŒ or ์œ ํŠœ๋ธŒ ์˜์ƒ ๋ชฉ๋ก ๋“ฑ์˜ ๊ตฌํ˜„.

- ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฐฐ์—ด(array) ์‚ฌ์šฉ

 

 

๋ฐฐ์—ด ์•ˆ์— ๋‹ค์–‘ํ•œ ์ž๋ฃŒํ˜•์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Œ

>> JSX๋„ ๋ฐฐ์—ด์— ์ €์žฅ ๊ฐ€๋Šฅ.

 

map()ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ํ™”๋ฉด์„ ์†์‰ฝ๊ฒŒ ์ถœ๋ ฅ(rendering) ๊ฐ€๋Šฅ.

 

const toDoList = [
  { taskName: "๋นจ๋ž˜ํ•˜๊ธฐ", finished: false },
  { taskName: "๊ณต๋ถ€ํ•˜๊ธฐ", finished: true },
];


const toDos = toDoList.map(todo => <li>{todo.taskName}</li> );
// JSX๋กœ ๋ณ€๊ฒฝ๋„ ๊ฐ€๋Šฅ
const toDos = toDoList.map(todo => <TodoTask taskname={todo.taskName} />);

// return ๋ถ€๋ถ„
return(
  <div>
      <ul>
         {toDos}
      </ul>
  </div>

 

 

 

๐Ÿ™‹‍โ™‚๏ธ map() ์ด์šฉํ•˜์—ฌ ๋ฐฐ์—ด ์ปดํฌ๋„ŒํŠธ ์ถœ๋ ฅ

 

- ๋ฐ”๋กœ render() ์•ˆ์—์„œ map()ํ•จ์ˆ˜๋กœ ์ถœ๋ ฅํ•˜๋Š” ๋ฐฉ๋ฒ•.

render() {
   const toDoList = [
      { taskName: "๋นจ๋ž˜ํ•˜๊ธฐ", finished: false },
      { taskName: "๊ณต๋ถ€ํ•˜๊ธฐ", finished: true },
    ];
    
    return (
       <div>
          <ul>
             {toDoList.map(todo => <li> {todo.taskName} </li>);}
          </ul>
       </div>
    );
}

 

 

โ—โ— ์ฃผ์˜์‚ฌํ•ญ

  • ๋ฐฐ์—ด ์ปดํฌ๋„ŒํŠธ๋Š” ๋ฐฐ์—ด ์š”์†Œ์˜ ๊ฐœ์ˆ˜๋งŒํผ map์— ์˜ํ•ด ๋ฐ˜๋ณต๋˜๋ฏ€๋กœ ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ๋งŽ์ด ์ค€๋‹ค.
  • ๋”ฐ๋ผ์„œ ๋ฐฐ์—ด ์ปดํฌ๋„ŒํŠธ์—๋Š” ๊ผญ key๊ฐ’์„ ์ •์˜ํ•ด์ค˜์•ผํ•œ๋‹ค.
  • ์ถœ๋ ฅํ•œ ๋ฐฐ์—ด ์ปดํฌ๋„ŒํŠธ๋Š” ๋‹ค์‹œ ์ถœ๋ ฅํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ, ๋ฆฌ์•กํŠธ๊ฐ€ ๊ธฐ์กด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์žฌํ™œ์šฉํ•จ.

 

 

 

render() {
   const toDoList = [
      { taskName: "๋นจ๋ž˜ํ•˜๊ธฐ", finished: false },
      { taskName: "๊ณต๋ถ€ํ•˜๊ธฐ", finished: true },
    ];
    
    return (
       <div>
          <ul>
             {toDoList.map(todo, index => <li key={`list_${index}`}> {todo.taskName} </li>);}
          </ul>
       </div>
    );
}

- ํ‚ค๊ฐ’์œผ๋กœ ๊ณ ์œ ํ•œ ๋ฐฐ์—ด ํ•ญ๋ชฉ์„ ์‚ฌ์šฉํ•ด์•ผ ๋น„ํšจ์œจ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋จ.

(์œ„์—์ฒ˜๋Ÿผ ์ธ๋ฑ์Šค ๋ฒˆํ˜ธ๋ฅผ ํ‚ค๋กœ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ๋งŒ์•ฝ ๋‚˜์ค‘์— ํ•ญ๋ชฉ์ด ์‚ฌ๋ผ์ง€๊ฒŒ ํ•ด์„œ ์ธ๋ฑ์Šค๊ฐ€ ์‚ฌ๋ผ์ง€๋ฉด, ํ‚ค๊ฐ’๋„ ์‚ฌ๋ผ์ง.)

- taskName์— ๊ณ ์œ ํ•œ ๊ฐ’์ด ๋“ค์–ด์žˆ์œผ๋ฏ€๋กœ, ์ด๋ฅผ ํ‚ค๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹๋‹ค.

 

 

๊ฒฐ๋ก :   key๊ฐ’์œผ๋กœ ๋ฌด์กฐ๊ฑด index๋ฅผ ์“ด๋‹ค? - ๋น„์ถ”์ฒœ.

 

๐Ÿ”ป key๊ฐ’์œผ๋กœ taskName์„ ์‚ฌ์šฉ

render() {
   const toDoList = [
      { taskName: "๋นจ๋ž˜ํ•˜๊ธฐ", finished: false },
      { taskName: "๊ณต๋ถ€ํ•˜๊ธฐ", finished: true },
    ];
    
    return (
       <div>
          <ul>
             {toDoList.map(todo, index => <li key={todo.taskName}> {todo.taskName} </li>);}
          </ul>
       </div>
    );
}

 

 

 

 

๐Ÿ™‹‍โ™‚๏ธ render()์—์„œ ์—ฌ๋Ÿฌ๊ฐœ์˜ JSX ๋…ธ๋“œ ๋ฐ˜ํ™˜

 

- render()์€ ํŠธ๋ฆฌ๊ตฌ์กฐ์˜ ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•จ.

- ๋ฆฌ์•กํŠธ๋Š” ํŠธ๋ฆฌ ๋ง๊ณ ๋„ ๋ฐฐ์—ด๊ตฌ์กฐ์˜ ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Œ!

 

์˜ˆ> <button type="button"> Click! </button>์„ 3๊ฐœ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์‹ถ์„ ๋•Œ

 

...
render() {
   return (
      <button type="button"> Click! </button>
      <button type="button"> Click! </button>
      <button type="button"> Click! </button>
  )
}

// โ— Error

 

๋ฆฌ์•กํŠธ 16.3 ๊นŒ์ง€๋Š” render()ํ•จ์ˆ˜๋Š” ํŠธ๋ฆฌ๊ตฌ์กฐ์˜ ๋…ธ๋“œ 1๊ฐœ๊นŒ์ง€๋งŒ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๊ณ ,

์—ฌ๋Ÿฌ ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ ค๋ฉด ์˜๋ฏธ์—†๋Š” <div>๋กœ ๊ฐ์‹ธ์ค˜์•ผ ํ–ˆ๋‹ค.

 

๋ฆฌ์•กํŠธ 16.3 ์ดํ›„๋กœ๋Š” React.Fragment ์ปดํฌ๋„ŒํŠธ์˜ ์ถ”๊ฐ€๋กœ,

์˜๋ฏธ์—†๋Š” ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ๊ฐœ์„ ํ•˜์˜€๋‹ค.

 

React.Fragement

 

์—ฌ๋Ÿฌ ๋…ธ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ฐ˜ํ™˜.

์ด ์ปดํฌ๋„ŒํŠธ๋Š” HTML ๋กœ ๋ณ€ํ™˜๋˜์ง€ ์•Š์Œ.

 

render() { 
    return (
    	<React.Fragment>
    	    <button></button>
            <button></button>
            <button></button>
        </React.Fragment>
    );
  }
render() { 
    return (
    	<>
    	    <button></button>
            <button></button>
            <button></button>
        </>
    );
  }

<React.Fragment> </React.Fragment>

๋˜๋Š”

<> </>

๋กœ ์—ฌ๋Ÿฌ ๋…ธ๋“œ๋ฅผ ๊ฐ์‹ธ์ฃผ๋ฉด ๋œ๋‹ค!

 

 

 

 

+) map์˜ ์‚ฌ์šฉ

render() {
  return [1,2,3].map((num) => (
    <input type="radio" name="option1" key={`${num}`} value={num} />
  ))
}

 

 

 

์ปดํฌ๋„ŒํŠธ์—์„œ์˜ ์ฝœ๋ฐฑ๊ณผ ์ด๋ฒคํŠธ๋ฆฌ์Šค๋„ˆ

 

ํ”„๋กœํผํ‹ฐ (props) ์‚ฌ์šฉ์‹œ - ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌ ๊ฐ€๋Šฅ. (Read Only)

 

๋งŒ์•ฝ, ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•  ๋•Œ๋Š”?

- ํ”„๋กœํผํ‹ฐ ์›๋ณธ์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์— ๊ฐ™์ด ๋„˜๊ฒจ์คŒ.

๐Ÿ’ก ์ฝœ๋ฐฑ ํ•จ์ˆ˜
- ์ •์˜๋œ ์œ„์น˜์—์„œ ์‹คํ–‰๋˜์ง€ ์•Š๊ณ , ์ดํ›„ ํŠน์ • ์ƒํ™ฉ์—์„œ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜

 

 

์˜ˆ์ œ - Counter

 

App.jsx

import React from 'react';
import Counter from "./Counter";

class App extends Component {
  state = {
    count: 1,
  };

  increaseCount = () => {
    this.setState(({ count }) => ({ count: count + 1 }));
  };

  render() {
    return <Counter count={this.state.count} />;
  }
}

export default App;

 

 

์ง€๊ธˆ์€ App์ปดํฌ๋„ŒํŠธ์—์„œ state๋กœ ๊ด€๋ฆฌํ•˜๋Š” count๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์ง€๋งŒ,

ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์ธ Counter ์ปดํฌ๋„ŒํŠธ์—์„  count๋ฅผ ๋ณ€๊ฒฝ์‹œํ‚ฌ ์ˆ˜ ์—†๋‹ค.

(๊ทธ์ € props ๋กœ count๋ฅผ ๋ฐ›์•„์„œ ํ™”๋ฉด์— ๋ณด์ด๊ฒŒ๋งŒ ํ•  ์ˆ˜ ์žˆ์Œ)

 

 

App ์ปดํฌ๋„ŒํŠธ์—์„œ increaseCount()ํ•จ์ˆ˜๋ฅผ ํ”„๋กœํผํ‹ฐ ํ˜•ํƒœ๋กœ ์ „๋‹ฌํ•˜๋ฉด - Counter์—์„œ๋„ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ!

 

 render() {
    return <Counter count={this.state.count} onAdd={this.increaseCount} />;
  }

์ด๋Ÿฐ์‹์œผ๋กœ props๋กœ ์ „๋‹ฌํ•ด์ฃผ๊ณ , ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์ธ Counter์—์„œ๋Š”

 

 

Counter.jsx

import React from "react";
import PropTypes from "prop-types";

class Counter extends Component {
  render() {
    return (
      <div>
        ํ˜„์žฌ ์นด์šดํŠธ: {this.props.count}
        <button onClick={() => this.props.onAdd()}>์นด์šดํŠธ ์ฆ๊ฐ€</button>
      </div>
    );
  }
}

Counter.propTypes = {
  count: PropTypes.number,
  onAdd: PropTypes.func,
};

export default Counter;

 

<button onClick={() => this.props.onAdd()}>์นด์šดํŠธ ์ฆ๊ฐ€</button>

์ด๋ถ€๋ถ„์„ ๋ณด๋ฉด, onClick = {() => this.props.onAdd()}์™€ ๊ฐ™์ด ์ฝœ๋ฐฑ์˜ ํ˜•ํƒœ๋กœ (arrow function) ์ž‘์„ฑํ•ด์ค€๋‹ค.

 

 

๊ทธ๋Ÿฌ๋‚˜, ์ด๋Œ€๋กœ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๋ฐ,

์ด๋Š” ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ฐธ์กฐํ•  this์˜ ๋ฒ”์œ„์— ๋Œ€ํ•œ ์˜ค๋ฅ˜ ๋•Œ๋ฌธ์ด๋‹ค.

 

์ƒ์œ„->ํ•˜์œ„๋กœ ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ props๋กœ ๋ณด๋‚ด๋Š” ๊ฒฝ์šฐ์—๋Š”
ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ฐธ์กฐํ•  this ๋ฒ”์œ„๋ฅผ bind()๋กœ ์ง€์ •ํ•ด์ค˜์•ผํ•œ๋‹ค.

 

 

App.jsx ์ˆ˜์ •

import React from 'react';
import Counter from "./Counter";

class App extends Component {
   constructor(props) {
      super(props);
      this.increateCount = this.increateCount.bind(this);
      }
      
  	state = {
    count: 1,
  	};

  increaseCount = () => {
    this.setState(({ count }) => ({ count: count + 1 }));
  };

  render() {
    return <Counter count={this.state.count} />;
  }
}

export default App;

 

 

 

- ์ปดํฌ๋„ŒํŠธ์—์„œ window.addEventListner() ํ•จ์ˆ˜์™€ ๊ฐ™์€ DOM๊ฐ์ฒด ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋ ค๋ฉด

DOM๊ฐ์ฒด๋ฅผ ์ปดํฌ๋„ŒํŠธ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•ด์•ผํ•จ.

 

>> ref๋ฅผ ์‚ฌ์šฉํ•˜์ž.

 

 

import React from "react";

export default class ScrollSpy extends React.PureComponent {
  constructor(props) {
    super(props);
    this.setRef = this.setRef.bind(this);
    this.checkPosition = this.checkPosition.bind(this);
    window.addEventListener("scroll", this.checkPosition);
  }

  setRef(ref) {
    this.ref = ref;
  }

  checkPosition() {
    if (this.ref.getBoundingClientRect().top < window.innerHeight) {
      console.log("enter");   // ํ˜„์žฌ ์Šคํฌ๋กค ํ™”๋ฉด ์•ˆํŒŽ์ธ์ง€ ์ธก์ •
    } else {
      console.log("exit");
    }
  }

  componentDidMount() {
    this.checkPosition();
  }

  componentWillUnmount() {
    window.removeEventListener("scroll", this.checkPosition);
  }

  render() {
    return <div ref={this.setRef} />;
  }
}

 

- ์œˆ๋„์šฐ์˜ ์Šคํฌ๋กค ์ด๋™ ์ด๋ฒคํŠธ์‹œ >> checkPosition ์‹คํ–‰

- ref ํ”„๋กœํผํ‹ฐ์—์„œ ๋ฐ˜ํ™˜๋œ ๊ฐ์ฒด๋ฅผ this.ref ๋ณ€์ˆ˜์— ํ• ๋‹น.

 

return <div ref={this.setRef} />๋กœ

this.setRef์˜ ์ธ์ž๋กœ ํ•ด๋‹น DOM๊ฐ์ฒด๊ฐ€ ์ „๋‹ฌ๋˜๊ณ , this.ref (์ปดํฌ๋„ŒํŠธ ๋ณ€์ˆ˜)์— ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ํ• ๋‹นํ•ด์คŒ.

 

 

props๋กœ ์ „๋‹ฌ๋œ ์ฝœ๋ฐฑํ•จ์ˆ˜๋Š”

onClick = {this.resetCount} ์™€ ๊ฐ™์ด ์‚ฌ์šฉ ๊ฐ€๋Šฅ.

 


 

์ •๋ฆฌ

๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๋Š”? ๋‹จ๋ฐฉํ–ฅ ํ๋ฆ„ ๋ฐฉ์‹

state์™€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์œ„->ํ•˜์œ„๋กœ ์ „๋‹ฌ. (props)

 

๐Ÿ™‹‍โ™‚๏ธ props๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด?

 

์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์›๋ณธ ๋ฐ์ดํ„ฐ๊ฐ€ ์œ„์น˜ํ•œ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ 

๋‹ค์‹œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌํ•˜๋„๋ก ํ•จ.

 

๋‹จ๋ฐฉํ–ฅ ํ๋ฆ„ ๋ฐฉ์‹ - ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ ์ง€์ผœ์คŒ.

๋ฐ์ดํ„ฐ ์ˆ˜์ •์œผ๋กœ ์ธํ•œ ๋ฐ์ดํ„ฐ์˜ ํŒŒํŽธํ™”๋ฅผ ์ค„์—ฌ์คŒ.

'WEB STUDY > REACT' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

React. styled-components  (0) 2022.05.01
220317 TIL - markdown ver.  (0) 2022.03.17
220316 [TIL] Today I Learned ๐Ÿ’ฏ React.js  (0) 2022.03.16
220315 [TIL] Today I Learned ๐Ÿ’ฏ React.js - (2)  (0) 2022.03.15
220315 [TIL] Today I Learned ๐Ÿ’ฏ React.js - (1)  (0) 2022.03.15