March 01, 2020
๋งจ์ฒ์ ์ดํ๋ฆฌ์ผ์ด์ ์ผ๋ก TodoList ๋ณด๋ค ๋ ๊ธฐ๋ณธ์ ์ง์คํ ์ ์๋ ๊ณ์ฐ๊ธฐ๋ฅผ ํํ๋ค.
๋ชจ๋ ์ฐ์ฐ์ ๋ง์ ๋บ์ ์ผ๋ก ์ด๋ค์ง๋ค..!
์ ์ฒด container๋ pixel๋ก ๊ณ ์ ์ ์ธ ํฌ๊ธฐ๋ฅผ ์ก์์ฃผ์๊ณ
์์ ๋ฐฐ์น ๋ ์ด์์์ flex box๋ก ์ก์๋ณด์๋ค.
๋น ..๋!
๐ฅ ๋ ์ด์์์ ๋ด๊ฐ ์ํ๋๋๋ก ์กํ๋๋ฐ ๋ฐ์ 0, ., = ๋ฒํผ์ด ์ด์ง ๋ง์ง ์์๋ค.
flex container์ ์์ ์์ฑ์ผ๋ก ์๋์ ์ธ ํฌ๊ธฐ๋ฅผ ๋ง์ถ๊ธฐ ์ํด ๋๋จธ์ง ๋ฒํผ๋ค์ flex : 1
๋ก ์ฃผ๊ณ 0๋ฒํผ๋ง flex : 2
๋ก ์ฃผ์๋๋ฐ ์์๋ค์ ์๋์ ํฌ๊ธฐ์ margin๊ฐ๋ ํฌํจํ๋ฉด์ ๋ฑ๋ง๋ ๋ ์ด์์์ด ๋์ค์ง ์์ ๊ฒ ๊ฐ๋ค. ๊ทผ๋ฐ ๋์์ธ์์ฒด๋ก ๊ทธ๋ ๊ฒ ๋์์ง ์๋ค๋ ํฉ๋ฆฌํ๋ก ๊ทธ๋ฅ ๋์๋ค.
๋ฒฝ๋์.. ๋ ์ด์์.. masonry ๋์์ธ์ด์์..
์ผ๋ฐ์ ์ธ ๊ณ์ฐ๊ธฐ๋ result ๊ฐ๊ณผ ํ์ฌ ์ ๋ ฅ๊ฐ์ ๋ณด์ฌ์ฃผ๋ display๊ฐ 1๊ฐ์กด์ฌํ๋ค.
์ฆ, ํ์ฌ์
๋ ฅ๊ฐ์ ๋ณด์ฌ์ค ๋๋ ํ์ฌ ์ ์ฅ๋์ด์๋ result๊ฐ์ ๋ณผ ์ ์๋ค๋ ๋ถํธํ ์
์ด ์์๋ค.
๊ทธ๋์ ๊ฐ์ ๋ํ display ๋ทฐ๋ฅผ
- ์ ์ฅ๋ result๊ฐ + ์ ๋ ฅํ operator ๋ฅผ ๋ณด์ฌ์ฃผ๋ ๋ทฐ
- ํ์ฌ ์ ๋ ฅ๊ฐ ํน์ ์ต์ข ๊ฒฐ๊ณผ๊ฐ์ ๋ณด์ฌ์ฃผ๋ ๋ทฐ
๋๊ฐ๋ฅผ ๋ง๋ค์๋ค.
Title์ styled-component์ด๋ค.
<Title>
{tempResult + (pressedOperator === 'equal' ? '' : pressedOperator) ||
'Calculator'}
</Title>
tempResult๋ ์ ์ฅ๋ ๊ฐ์ด๊ณ , ์ด๊ธฐ tempResult ๊ฐ์ โ๋ก, ์ ์ฅ๋ ๊ฐ์ด ์์ ๊ฒฝ์ฐ โCalculatorโ๊ฐ ์ฐํ๋๋ก ํ์๋ค.
ResultContainer, ResultText, ResultNumber๋ styled-component์ด๋ค.
<ResultContainer>
<ResultText>Result</ResultText>
<ResultNumber>{result}</ResultNumber>
</ResultContainer>
๊ทธ๋ฆฌ๊ณ ์ ์ฒด ๊ฒฐ๊ณผ๊ฐ ํน์ ํ์ฌ ์ ๋ ฅ๊ฐ result์ ๋ทฐ๋ ๊ตฌ์ฑํด์ฃผ์๋ค.
const data = useSelector(state => state.calculator)
const [result, setResult] = useState(data.result || '0')
const [tempResult, setTempResult] = useState(data.tempResult || '')
const [pressedOperator, setPressedOperator] = useState(
data.pressedOperator || ''
)
const [isFirstNumberTyping, setIsFirstNumberTyping] = useState(
data.isFirstNumberTyping || false
)
์ปดํฌ๋ํธ๋ฅผ class ๊ฐ ์๋ ํจ์ํ
์ผ๋ก ๊ตฌ์ฑํ๊ณ ํด๋ก์ , hooks
๋ฅผ ์ด์ฉํด์ ์ปดํฌ๋ํธ ๋ด์์์ ์ํ๊ด๋ฆฌ๋ฅผ ํ์๋ค.
์ํ๋ณ์๋
result
: ํ์ฌ ์ ๋ ฅ๊ฐ || ์ต์ข ๊ฒฐ๊ณผ ๊ฐ
tempResult
: ์ ์ฅ๋ ๊ฒฐ๊ณผ๊ฐ
pressedOperator
: ์ ์ฅ๋ operator
isFirstNumberTyping
: operand๋ฅผ ์ฒ์์น๋์ง ํ์ธํ๋ ๋ณ์
๊ณ์ฐ๊ธฐ์์ number๋ฅผ ์ ๋ ฅํ๋ฉด string์ ๋ํ๋ฏ์ด ๋์์ผํ๋ค.
1 + 1 => 11
ํ์ง๋ง ์ฒ์ ์ด๊ธฐ๊ฐ์ 0์ธ๋ฐ ์์ฒ๋ผ ์ ๋ ฅํ๋ฉด
0 + 1 => not 1 but 01
์ด ํ๋ฉด์ ์ถ๋ ฅ๋๋ค.
์ด ํ์์ ๋ง๊ธฐ ์ํด์ isFirstNumberTyping ๋ณ์๋ฅผ ๋๊ณ ์ฒ์ ์ ๋ ฅ์์๋ ์ฒ์ ์ ๋ ฅํ number๊ฐ ๊ฒฐ๊ณผ๊ฐ์ ๋ค์ด๊ฐ๋๋ก ์ค์ ํด์ฃผ์๋ค.
๋ฌผ๋ก ์ฒซ ํ์ดํ number๊ฐ 0์ผ ๊ฒฝ์ฐ์ ์กฐ๊ฑด์ฒดํฌ๋ ํด์คฌ๋ค.
์ฒ์ ์ปดํฌ๋ํธ๋ฅผ ๊ตฌ์ฑํ ๋, calculator reducer์ ์ด๊ธฐ๊ฐ์ ๊ฐ์ ธ์ค๋๋ก ์ค์ ํ๋ค.
๊ทธ๋ฆฌ๊ณ ๋ค๋ฅธ ์ดํ๋ฆฌ์ผ์ด์ ์ ์ฐ๊ธฐ ์ํด ์ด ๊ณ์ฐ๊ธฐ ์ดํ๋ฆฌ์ผ์ด์ ์ ์ ์ Docker์ ๋ฃ์์ ๋, ํ์ฌ ๋ฆฌ์กํธ state๋ฅผ ๋ฆฌ๋์ค state๋ก ์ฎ๊ธฐ๋๋ก ์ค์ ํ๋ค.
์ฆ, ํด๋น ์ดํ๋ฆฌ์ผ์ด์ ์ state ์กฐ์์ ๋ฆฌ์กํธ๋ก,
ํด๋น ์ดํ๋ฆฌ์ผ์ด์ ์ state ์์์ ์ฅ( Docker ๋๊ธฐ๊ธฐ )์ ๋ฆฌ๋์ค๋ก ํ์๋ค.
CaculatorButtonRow๋ styled-component์ด๋ค.
<CaculatorButtonRow>
<button
name="1"
type="button"
onClick={e => buttonClickHandler(e.target.name)}
>
1
</button>
<button
name="2"
type="button"
onClick={e => buttonClickHandler(e.target.name)}
>
2
</button>
<button
name="3"
type="button"
onClick={e => buttonClickHandler(e.target.name)}
>
3
</button>
<button
className="rightButton"
name="multiple"
type="button"
onClick={e => buttonClickHandler(e.target.name)}
>
*
</button>
</CaculatorButtonRow>
๊ณ์ฐ๊ธฐ ์ดํ๋ฆฌ์ผ์ด์
์ ์๋ ๋ชจ~๋ ๋ฒํผ์ click ์ด๋ฒคํธํธ๋ค๋ฌ ํจ์๋ buttonClickHandler
ํจ์๋ก ํต์ผ ์์ผ์ฃผ์๋ค.
๋ฒํผ๋ง๋ค name์ ์ ์ด์ฃผ๊ณ e.target.name์ ํจ์์ ์ ๋ฌํด์ค์ผ๋ก์, ํด๋น ํจ์์์ ์ ๋ฌ๋ฐ์ ๊ฐ์ ๋ฐ๋ผ ๋ก์ง์ ์ฒ๋ฆฌํ๊ฒ๋ ํด์ฃผ์๋ค.
const buttonClickHandler = button_type => {
if (button_type === 'reset') {
setResult('0')
setTempResult('')
setPressedOperator('')
} else if (button_type === 'delete') {
if (result === '0') return
result.length === 1
? (setResult('0'), setIsFirstNumberTyping(true))
: setResult(result.substr(0, result.length - 1))
} else if (button_type === 'plus') {
const block_result = operating(pressedOperator)
setTempResult(block_result)
setPressedOperator('plus')
setIsFirstNumberTyping(true)
if (pressedOperator !== '') {
setResult(block_result)
}
} else if (button_type === 'minus') {
const block_result = operating(pressedOperator)
setTempResult(block_result)
setPressedOperator('minus')
setIsFirstNumberTyping(true)
if (pressedOperator !== '') {
setResult(block_result)
}
} else if (button_type === 'multiple') {
const block_result = operating(pressedOperator)
setTempResult(block_result)
setPressedOperator('multiple')
setIsFirstNumberTyping(true)
if (pressedOperator !== '') {
setResult(block_result)
}
} else if (button_type === 'divide') {
const block_result = operating(pressedOperator)
setTempResult(block_result)
setPressedOperator('divide')
setIsFirstNumberTyping(true)
if (pressedOperator !== '') {
setResult(block_result)
}
} else if (button_type === 'equal') {
const block_result = operating(pressedOperator)
setTempResult(block_result)
setPressedOperator('equal')
setIsFirstNumberTyping(true)
if (pressedOperator !== '') {
setResult(block_result)
}
} else if (button_type === 'period') {
if (result.indexOf('.') < 0) {
setResult(result + '.')
}
setIsFirstNumberTyping(false)
} else if (button_type === 'toggleSign') {
setResult(result[0] === '-' ? result.substr(1) : '-' + result)
} else if (
button_type === '1' ||
'2' ||
'3' ||
'4' ||
'5' ||
'6' ||
'7' ||
'8' ||
'9' ||
'0'
) {
if (isFirstNumberTyping) {
setResult(button_type)
setIsFirstNumberTyping(false)
} else {
result[0] === '0'
? setResult(button_type)
: setResult(result + button_type)
}
}
}
const operating = operator_type => {
if (operator_type === 'plus')
return String(Number(tempResult) + Number(result))
else if (operator_type === 'minus')
return String(Number(tempResult) - Number(result))
else if (operator_type === 'multiple')
return String(
tempResult === '' ? Number(result) : Number(tempResult) * Number(result)
)
else if (operator_type === 'divide')
return String(
tempResult === '' ? Number(result) : Number(tempResult) / Number(result)
)
else return String(Number(result))
}
๊ณ์ฐ๊ธฐ ํ๋ก๊ทธ๋จ์ number๋ฅผ ์ ๋ ฅํ๊ณ operator๋ฅผ ์ ๋ ฅํ๊ณ ๋ค์ number๋ฅผ ์ ๋ ฅํ๋ ์์ผ๋ก ๊ฐ์ ๊ณ์ฐํ๋ค.
1 + 3 * 2 ์์ผ๋ก ๋๋ฅด๋ฉด 7์ด ์๋๋ผ, 8์ด ๋์ด.
์ฆ, 1 + 3 ๊น์ง ๋๋ฅด๊ณ *๋ฅผ ๋๋ ์ ๋, ํ๋ก๊ทธ๋จ์ *๋ฅผ ์ํํ๋ ๊ฒ์ด ์๋๋ผ +๋ฅผ ์ํํ๊ณ *๋ฅผ ์ ์ฅํ๋ ๋ฐฉ์์ผ๋ก ๊ณ์ฐํด์ผํ๋ค.
๊ทธ๋์ e.target.name์ operator๊ฐ ๋ค์ด์ค๋ฉด ์ ์ฅ๋ operator๋ฅผ ํตํด์ operating ํจ์๋ฅผ ๋จผ์ ์คํํ๊ฒ๋ ํ์๋ค.
์์์ ์ธ๊ธํ๋ฏ์ด, 0๋ฒํผ์ด ๋ฒํผ ๋๊ฐ์ ํฌ๊ธฐ๋งํผ ๋ค์ด๋ง์ง๋ ์๋๋ค.
์ซ์๊ฐ ์ธ์๋ฆฌ์๋ฅผ ์ด๊ณผํ ๋๋ง๋ค ,๋ฅผ ์ฐ๋ ๊ธฐ๋ฅ์ด ์๋ค.
ex) 1,000,000
๊ณ์ฐ๊ธฐ์ period(์ ), ๋ถํธ ๋ฑ์ ๋ชจ๋ ๊ฐ์ length ๋ณํ๋ฅผ ์ค๋ค. ํ์ง๋ง ,(์ฝค๋ง)๋ฅผ ๋ฃ์ผ๋ ค๋ฉด ์ด๋ฐ length ๋ณํ์ ๋ฐ๋ฅธ ์ฒ๋ฆฌ๋ฅผ ๋ค์ ํด์ค์ผํ๋๋ฐ ํ์ง ์์๋ค.