March 01, 2020
๊ธฐ๋ณธ๊ธฐ๋ฅผ ์ผ์ถ(๋ ์ผ์ถ์ผ?) ๊ณต๋ถํ๋ฉด์ ์ฌ๋ฌ๊ฐ์ง ๋ ์ค๋ฅด๋ ์์ด๋์ด๋ค์ ๋ฉ๋ชจ์ฅ์ ์ ์ด๋๋ค.
์์ด๋์ด๋ค์ ์ค์ ์ฌ์ฉ์๋ค์ด ์ฌ์ฉํ๋ฉด ์ด๋จ๊นํ๋ ๋ณตํฉ์ ์ธ ์๋น์ค๋ถํฐ
์ฌ์ํ ์ธํฐ๋ ์ ๊ธฐ๋ฅ๊น์ง ๋ญ๊ฐ ๋ง๋ค ์ ์๋, ๋ง๋ค๊ณ ์ถ์ ๋ชจ๋ ๊ฒ๋ค์ ์ฐจ๊ณก์ฐจ๊ณก ์์๋์๋ค.
๊ทผ๋ฐ ์ฒ์๋ถํฐ ๊ฑฐ๋ํ ์์คํ ์ ๋ง๋๋ ๊ฒ๋ณด๋ค๋ ์ฌ์ํ ๊ธฐ๋ฅ๋ค์ ๋ง๋ค์ด๋ณด๋ ํ๋ก์ ํธ๋ฅผ ํ์๋ ์๊ฐ์ ํ๋ค.
- ์ด๋ฒ ํ๋ก์ ํธ์ ๋ชฉ์ ์ ๊ณต๋ถ์ด๋ค.
- ๊ฐ๋ฐ์ ํ์ ํ๋ ๊ฒ์ด์ง๋ง ๊ฐ์ธํ๋ก์ ํธ๋ ์์ ์ด ํ ์ ์๊ณ , ํ๊ณ ์ถ์ ๋ถ์ผ์ ์ง์คํ๋ ๊ฒ์ด ๋ซ๊ฒ ๋ค๋ผ๋ ํ๋จ์ ํ๋ค.
๊ฐ๋ฐ์ ๋งค๋ ฅ์ ๋๋ผ๊ฒ๋ ๊ณ๊ธฐ๋ฅผ ๋ง๋ฒ์ผ๋ก ํํํ๋ฏ์ด (๋ธ๋ก๊ทธ๋ฅผ ์์ํ๋ฉฐ)
ํ๋ก์ ํธ๋ช
์ ์๋ง๋ฒ ํ๋ก์ ํธ
๋ก ์ง์๋ค. (a.k.a ํ ์ดํ๋ก์ ํธ)
์ด๋ฒํ๋ก์ ํธ๋ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋ฅ๋ค๊ณผ ๋ก์ง, ํน์ ๋์์ธ(ux,ui)์ ํฌ์ปค์ค๋ฅผ ๋ง์ถ๊ณ ์์ผ๋ก ๋ด๊ฐ ๊ตฌ์ํ ๊ฒ์ ์ค์ ๋ก ๊ตฌํํด๋ณด๊ณ ์ํ๋ค.
๋ฌผ๋ก ๊ณต๋ถ์ ๋ชฉ์ ์ด๊ธฐ ๋๋ฌธ์ ์ต๋ํ ํ๋ก์ ํธ๋ฅผ ํ๋ฉด์ ๋๋ ๊ฒ์ด๋ ๋ฐฐ์ด ๊ฒ๋ค์ ๋ธ๋ก๊ทธ์ ๊ธฐ๋กํ ๊ฒ์ด๋ค.
ํฐ ํ์ nextjs
ํ๋ ์์ํฌ๋ฅผ ํตํด ๋ผ์ฐํ
์์คํ
์ ์ฌ์ฉํ์ฌ ๋ฉ์ธํ์ด์ง์์ ๊ฐ๊ฐ์ ์ดํ๋ฆฌ์ผ์ด์
ํ์ด์ง๋ก ์ด๋ํ๋๋ก ๊ตฌ์ํ์๋ค.
๊ทธ๋ฆฌ๊ณ ๊ฐ ํ์ด์ง์ view๋ react
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ธฐ๋ก ํ๋ค.
์ํ๊ด๋ฆฌ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฆฌ์กํธ hooks๋ฅผ ํตํด์ ํ๋, ๊ฐ๊ฐ์ ์ดํ๋ฆฌ์ผ์ด์
์ ์ฌ๋ฌ๊ฐ ์ผ๋๊ฑฐ๋ ์ ์ background์ ๋ ๋์ฒ๋ผ ์ ์ฒด์ ์ธ ์ํ๊ด๋ฆฌ๋ redux
๋ฅผ ์ฌ์ฉํ์๋ค.
๋ฆฌ๋์ค๋ํ hooks๋ฅผ ์ฌ์ฉํ๋ ค ํ๋ค.
๊ทธ๋ฆฌ๊ณ ๋์์ธ์ props์ ๋ฌ์ด๋ ์ฌ์ฌ์ฉ์ฑ, ๊ด๋ฆฌ๊ฐ ์ข์ styled-component
๋ฅผ ์ ํํ๋ค.
๋ฉ์ธํ์ด์ง
์ ์ฒด์ ์ธ ๋์์ธ ์ปจ์
์ neumorphism
์ ์ฐ๊ธฐ๋ก ํ๋ค.
๋ชจ๋ํ๊ณ ๋ฏธ๋๋ฉ๋ฆฌ์ฆํฑํ ๋๋๋ ๋๋ ค์ ์ ํํ๋ค.
๋ญ๊ฐ ๋ฒํผ์ ๋๋ฅด๊ณ ์ถ๊ฒ ํ๋ ux ์ ์ธ ์์๋ ์ข์๋ ๊ฒ ๊ฐ๋ค.
์ฌ์ค ux์ ์ผ๋ก ํฐ ๊ณ ๋ฏผ์ ํ๊ณ ์ ํ์ง ์์๋ค. (๊ทธ์ ์์ ๊ฒ ๊ฐ์์..)
์ด๋ฒ ํ๋ก์ ํธ ๋ด์ ์ฌ๋ฌ ์ดํ๋ฆฌ์ผ์ด์ (๊ธฐ๋ฅ๋ค)์ ๋ฃ๋ ๊ฒ์ ๊ตฌ์ํ์๊ณ
๊ทธ๋ฆฌ๊ณ ์ฌ๋ฌ ์ดํ๋ฆฌ์ผ์ด์ ์ ๋์์ ์ธ ์ ์๋ ๋ฉํฐํ์คํน๋ ๊ตฌ์ํด๋ณด์๋๋ฐ
๊ทธ๋ ๊ฒ ๋ ์ฌ๋ฆฐ ๋์์ธ ์ปจ์
์ด ๋งฅ๋ถ ๋ฐ์คํฌํ
ํํ์๋ค.
๋ฉ์ธํ์ด์ง์ ์ดํ๋ฆฌ์ผ์ด์ ์ ์์ด์ฝ ํ์์ผ๋ก ๋ฃ์ด๋๊ณ ํด๋ฆญํ์ฌ ์คํํ๋ฉฐ(๋ผ์ฐํ ),
์ดํ๋ฆฌ์ผ์ด์ ์ ์ข ๋ฃํ์ง ์๊ณ ๋ค๋ฅธ ์ดํ๋ฆฌ์ผ์ด์ ์ ์ฌ์ฉํ๋ค๊ฐ ๋ค์ ๋์์๋ ๋ฐ์ดํฐ๊ฐ ๋จ์์๋ ๊ฒ์ ์๊ฐํ๋ค.(๋ฆฌ๋์ค)
๊ทธ๋ ๊ฒ ํ๋จ์ Docker๋ฅผ ๋์๋ค.
ํ๋ก์ ํธ ๊ณต์ ๋ ์ด์์ (next์ App ์ปดํฌ๋ํธ!)๋ฅผ ํตํด
ํ๋ฉด ์๋จ ์ค์์๋ full screen ๋ชจ๋ ๋ฒํผ
๊ณผ ์ ์๋
ธํธ๋งํฌ ๋ฒํผ
์ ๋์๊ณ
ํ๋ฉด ์๋จ ์ฐ์ธก์๋ ๊นํ๋ธ ๋งํฌ๋ฅผ ๋์๋ค.
next ํ๋ ์์ํฌ์ ๋ผ์ฐํ ์์คํ
์ปดํฌ๋ํธ๋ค์ ๊ฐ ์ดํ๋ฆฌ์ผ์ด์ ์ ๋ฐ๋ก ํด๋๋ฅผ ๋์๊ณ , ์ ์ฒด์ ์ธ ๋ ์ด์์ ํน์ ๊ณตํต์ ์ผ๋ก ์ฌ์ฉ๋๋ ๋ถ๋ถ์ ๋ฃจํธ ๋๋ ํ ๋ฆฌ์ ๋์๋ค.
ํฐํธ, ์ด๋ฏธ์ง, ํ๋น์ฝ ๋ฑ ํ๋ก์ ํธ์ ์ฐ์ผ static file๋ค์ ๋ฃ์ด์ฃผ์๋ค.
๋ฆฌ๋์๋ ๊ฐ ์ดํ๋ฆฌ์ผ์ด์ ๋ณ๋ก ์ฝ๋ ์คํ๋ฆฌํ ํด์ฃผ์๋ค.
next ํ๋ ์์ํฌ๋ pages ๋๋ ํ ๋ฆฌ๋ฅผ ํตํด ๋ผ์ฐํ ์์คํ ์ ์ฌ์ฉํ ์ ์๋ค.
๐ฅ _error.js๋ก Error์ปดํฌ๋ํธ ์ปค์คํฐ๋ง์ด์งํ๊ธฐ
App ์ปดํฌ๋ํธ๋ ๋ค์ ๋ฐฉ์์ผ๋ก ์ปค์คํฐ๋ง์ด์ง ํด๋ณด์๋ค.
import React from 'react'
import { GlobalStyle } from '../reset.css.js'
import { Provider } from 'react-redux'
import withRedux from 'next-redux-wrapper'
import { applyMiddleware, compose, createStore } from 'redux'
import reducer from '../reducers'
import Background from '../components/Background.js'
const _app = ({ Component, store }) => {
return (
<>
{/* โญ ๊ธ๋ก๋ฒ์คํ์ผ*/}
<GlobalStyle />
<Provider store={store}>
{/* โญ ๊ณตํต ๋ ์ด์์*/}
<Background>
<Component />
</Background>
</Provider>
</>
)
}
const configureStore = (initialState, options) => {
const middlewares = []
const enhancer =
process.env.NODE_ENV === 'production'
? compose(applyMiddleware(...middlewares))
: compose(
applyMiddleware(...middlewares),
!options.isServer &&
typeof window.__REDUX_DEVTOOLS_EXTENSION__ !== 'undefined'
? window.__REDUX_DEVTOOLS_EXTENSION__()
: f => f
)
const store = createStore(reducer, initialState, enhancer)
return store
}
export default withRedux(configureStore)(_app)
styled component์ createGloadStyle์ ์ด์ฉํด ์ ์ฒด์ ์ธ css๋ถ๋ถ์ reset.css.js ํ์ผ์ ๋ฃ์ด์ฃผ์๋ค.
// reset.css.js
import { createGlobalStyle } from 'styled-components'
export const GlobalStyle = createGlobalStyle`
// ...
`
๋ชจ๋ css ์์ฑ๊ณผ ๊ฐ์ resetํด์ฃผ๊ณ , ์ฌ์ฉํ ๋ก์ปฌ ํฐํธ ๋ฑ์ ๋ฃ์ด์ฃผ์๋ค.
Component (next์์๋ pages๋ฅผ ์๋ฏธ)๋ค์ Background ์ปดํฌ๋ํธ๋ก ๊ฐ์ธ์ฃผ์๋ค. Background ์ปดํฌ๋ํธ๋ ๋ชจ๋ ํ์ด์ง์์ ์ ์ฉ๋ ๋ ์ด์์ ์์ (Header, Footer ๋ฑ)๋ค์ ๋ค์ ๋ฃ์ด์ฃผ์๋ค.
// Background.js
import React from 'react'
import styled from 'styled-components'
import Header from './Header'
import Footer from './Footer'
const BackgroundContainer = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
background: #f5f6f7;
`
const FixedGithub = styled.div`
position: fixed;
z-index: 10;
right: 0;
top: 0;
margin: 6px;
& > img {
filter: invert(48%) sepia(13%) saturate(3207%) hue-rotate(130deg) brightness(
95%
) contrast(60%);
cursor: pointer;
}
`
const Background = ({ children }) => {
return (
<>
<BackgroundContainer>
<a href="https://github.com/taenykim/" target="_blank">
<FixedGithub>
<img src="./github.png" width="28" height="28" />
</FixedGithub>
</a>
<Header></Header>
{children}
<Footer></Footer>
</BackgroundContainer>
</>
)
}
export default Background
Document ์ปดํฌ๋ํธ๋ ๋ค์ ๋ฐฉ์์ผ๋ก ์ปค์คํฐ๋ง์ด์ง ํด๋ณด์๋ค.
import React from 'react'
import { ServerStyleSheet } from 'styled-components'
import Document, { Html, Head, Main, NextScript } from 'next/document'
class _document extends Document {
static getInitialProps({ renderPage }) {
const sheet = new ServerStyleSheet()
const page = renderPage(App => props =>
sheet.collectStyles(<App {...props} />)
)
const styleTags = sheet.getStyleElement()
return { ...page, styleTags }
}
render() {
return (
<Html>
<Head>{this.props.styleTags}</Head>
<body style={{ fontFamily: 'escore3' }}>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default _document
styled-components๊ฐ ๋ ๋๋ง ๋๊ณ ์ ์ฉ๋๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด
getInitialProps
๋ฅผ ํตํ์ฌ ์คํ์ผ์ ์ ์ฉ์ํจ ํ ๋ ๋๋ง์ ํ๋๋ก ์ค์ ํด์ฃผ์๋ค.
๋ฉ์ธํ์ด์ง
import React from 'react'
import styled from 'styled-components'
import AppIcon from '../components/AppIcon'
import AppName from '../components/AppName'
const IndexContainer = styled.div`
display: flex;
width: 90vw;
height: 90vh;
margin: 10px 10px 10px 10px;
`
const AppContainer = styled.div`
display: flex;
flex-direction: column;
align-items: center;
margin: 5px 20px 10px 20px;
`
const index = () => {
return (
<>
<IndexContainer>
<AppContainer>
<AppIcon name="calculator" />
<AppName name="calculator" />
</AppContainer>
<AppContainer>
<AppIcon name="graph" />
<AppName name="graph" />
</AppContainer>
</IndexContainer>
</>
)
}
export default index
๋ฉ์ธํ์ด์ง๋ AppIcon๊ณผ AppName ์ปดํฌ๋ํธ๋ฅผ importํด์ ๊ตฌ์ฑํ์๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฐ๊ฐ์ props๋ก ํด๋น ์ดํ๋ฆฌ์ผ์ด์ ์ด๋ฆ์ ๋๊ฒจ์ค์ ๊ฐ๊ฐ์ ์ปดํฌ๋ํธ์์ ์ง์ ๊ฐ์ด ๋ฐ๋๊ฒ๋
์ฝ๋ ์ฌ์ฌ์ฉ์ฑ
์ ์ด์ ์ ๋ง์ถฐ๋ณด์๋ค.
// calculator page
import React from 'react'
import Layout from '../components/calculator/Layout'
const calculator = () => {
return (
<>
<Layout />
</>
)
}
export default calculator
// graph page
import React from 'react'
import Layout from '../components/graph/Layout'
const graph = () => {
return (
<>
<Layout />
</>
)
}
export default graph
๊ฐ๊ฐ์ ํ์ด์ง์ ์ง์ ๊ธฐ๋ฅ๋ค์ ๋ฃ๋ ๊ฒ๋ณด๋ค ํด๋น ๊ธฐ๋ฅ๋ค์ด ๋ด๊ธด components ๋ฅผ ํ๋ฒ์ ๋ถ๋ฌ์ค๋ ๊ฒ์ด ๊ด๋ฆฌ๊ฐ ์ฌ์ธ ๊ฒ ๊ฐ์ components ๋๋ ํ ๋ฆฌ ๋ด์ ํด๋น application ์ด๋ฆ์ ๋๋ ํ ๋ฆฌ๋ฅผ ๋ง๋ค๊ณ layout ์ปดํฌ๋ํธ๋ฅผ ๋์๊ณ ๊ทธ๊ฒ์ ๋ถ๋ฌ์ค๋ ๋ฐฉ์์ผ๋ก ๊ตฌ์ฑํ์๋ค.
in Background Component
import React, { useEffect, useState } from 'react'
import styled from 'styled-components'
const HeaderContainer = styled.div`
display: flex;
position: fixed;
top: 0;
margin-top: 10px;
z-index: 5;
font-size: 12px;
font-family: escore6;
color: #666;
`
const FullscreenText = styled.p`
cursor: pointer;
`
const NoteText = styled.p`
cursor: pointer;
`
const Header = () => {
const [full, setFull] = useState(false)
useEffect(() => {
document.addEventListener('fullscreenchange', () => {
setFull(!full)
})
})
const openFullScreen = () => {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen()
} else {
document.exitFullscreen()
}
}
return (
<HeaderContainer>
<FullscreenText onClick={openFullScreen}>
{full ? 'exit full screen' : 'full screen'}
</FullscreenText>
| <NoteText>note</NoteText>
</HeaderContainer>
)
}
export default Header
full
state ๊ฐ์ false๋ก ๋๊ณ (hooks) document
๊ฐ์ฒด์ fullscreenchange ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ๋ฃ์ด์ฃผ์๊ณ ์ด๋ฒคํธ ๋ฐ์์ full state๊ฐ์ toggle ํ๋๋ก ํ์๋ค.pํ๊ทธ
์ click ์ด๋ฒคํธํธ๋ค๋ฌ๋ฅผ ๋ฃ์ด์ฃผ์๊ณ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ํ์ฌ ์คํฌ๋ฆฐ๋ชจ๋๋ฅผ ์ธ์ํด์ ์คํฌ๋ฆฐ๋ชจ๋๋ฅผ toggleํ๋๋ก ํ์๋ค.pํ๊ทธ
์ ์ ํ๋๋ก ํ์๋ค.in Background Component
import React from 'react'
import styled from 'styled-components'
import { useSelector } from 'react-redux'
import DockerIcon from './DockerIcon'
const FooterContainer = styled.div`
display: flex;
align-items: center;
position: fixed;
bottom: 0;
width: 100%;
height: 60px;
background: rgba(0, 0, 0, 0.85);
border-radius: 8px 8px 0px 0px;
`
const Docker = styled.div`
display: flex;
align-items: center;
padding: 0px 20px 0px 20px;
`
const Footer = () => {
const { docker } = useSelector(state => state.wrapper)
return (
<FooterContainer>
<Docker>
{docker.map((item, i) => {
// โญ
return <DockerIcon key={i} item={item} />
})}
</Docker>
</FooterContainer>
)
}
export default Footer
useSelector
๋ฅผ ํตํด docker array๋ฅผ ๊ฐ์ ธ์จ๋ค.DockerIcon
์ปดํฌ๋ํธ์ ์์์ ๊ฐ์ props๋ก ์ ๋ฌํ๊ณ ๋ทฐ๋ฅผ ๊ตฌ์ฑํ๋๋ก ํ๋ค.{
"docker": ["calculator"]
}
in Footer Component
import React from 'react'
import styled from 'styled-components'
import Link from 'next/link'
const AppIconContainer = styled.div`
display: flex;
justify-content: center;
align-items: center;
width: 40px;
height: 40px;
box-sizing: border-box;
border-radius: 15%;
background: #f5f6f7;
color: ${props => {
if (props.name === 'calculator') return 'red'
else if (props.name === 'graph') return 'blue'
else return 'black'
}};
margin-right: 10px;
& > div {
font-family: escore9;
font-size: 20px;
text-shadow: 3px 3px #ccc;
}
`
const DockerIcon = ({ item }) => {
const url = `/${item}`
return (
<Link href={url}>
<a style={{ textDecoration: 'none' }}>
<AppIconContainer name={item}>
<div>{item[0].toUpperCase()}</div>
</AppIconContainer>
</a>
</Link>
)
}
export default DockerIcon
in Application > layout Component
์ด ๋ถ๋ถ..!
import React from 'react'
import styled from 'styled-components'
import Link from 'next/link'
import { useDispatch } from 'react-redux'
import {
STORE_CALCULATOR_DATA,
STORE_RESET_CALCULATOR,
} from '../reducers/calculator'
import { STORE_GRAPH_DATA, STORE_RESET_GRAPH } from '../reducers/graph'
import { DOCKER_STORE, DOCKER_DELETE } from '../reducers/wrapper'
const ContentsMenubarContainer = styled.div`
display: flex;
align-items: center;
width: 100%;
height: 60px;
top: 0;
& img {
width: 17px;
height: 17px;
}
`
const ImageContainer = styled.div`
display: flex;
justify-content: center;
align-items: center;
height: 30px;
width: 30px;
box-shadow: -4px -2px 4px 0px #ffffff, 4px 2px 6px 0px #ddd;
border-radius: 2px;
padding: 2px;
&:hover {
cursor: pointer;
}
&:active {
box-shadow: 2px 2px 2px 0px #dfe4ea inset, -2px -2px 2px 0px white inset;
}
& > img {
filter: invert(48%) sepia(13%) saturate(3207%) hue-rotate(130deg) brightness(
95%
) contrast(80%);
}
`
// โญ props ?!
const ContentsMenubar = ({ data, name }) => {
const dispatch = useDispatch()
// โญ redux action dispatch ?!
const storeHandler = () => {
switch (name) {
case 'calculator': {
dispatch({
type: STORE_CALCULATOR_DATA,
data: data,
})
dispatch({
type: DOCKER_STORE,
data: name,
})
return
}
case 'graph': {
dispatch({
type: STORE_GRAPH_DATA,
data: data,
})
dispatch({
type: DOCKER_STORE,
data: name,
})
return
}
default: {
dispatch({
type: DOCKER_STORE,
data: name,
})
return
}
}
}
const storeReset = () => {
switch (name) {
case 'calculator': {
dispatch({
type: STORE_RESET_CALCULATOR,
})
dispatch({
type: DOCKER_DELETE,
data: name,
})
return
}
case 'graph': {
dispatch({
type: STORE_RESET_GRAPH,
})
dispatch({
type: DOCKER_DELETE,
data: name,
})
return
}
default: {
dispatch({
type: DOCKER_DELETE,
data: name,
})
return
}
}
}
return (
<ContentsMenubarContainer>
<Link href="/">
<a style={{ margin: '2px 2px 2px 10px' }}>
<ImageContainer onClick={storeReset}>
<img src="cancel.png"></img>
</ImageContainer>
</a>
</Link>
<Link href="/">
<a style={{ margin: '2px 2px 2px 10px' }}>
<ImageContainer onClick={storeHandler}>
<img src="bottom_arrow.png"></img>
</ImageContainer>
</a>
</Link>
</ContentsMenubarContainer>
)
}
export default ContentsMenubar
// calculator > layout.js
<ContentsMenubar
data={{ result, tempResult, pressedOperator, isFirstNumberTyping }}
name="calculator"
></ContentsMenubar>
data props
๋ฆฌ๋์ค ์คํ ์ด์ ์ ์ฅํ๊ณ ํ ๋ฐ์ดํฐ๋ค์ ๊ฐ์ฒดํํ๋ก ๋๊ฒจ์ค
name props
ํ์ฌ ์ดํ๋ฆฌ์ผ์ด์ ์ ์ด๋ฆ
export const initialState = {
docker: [],
}
export const DOCKER_STORE = 'DOCKER_STORE'
export const DOCKER_DELETE = 'DOCKER_DELETE'
export default (state = initialState, action) => {
switch (action.type) {
case DOCKER_STORE: {
// docker์ ํด๋น ์ดํ๋ฆฌ์ผ์ด์
์ด ์์ผ๋ฉด return
if (state.docker.indexOf(action.data) >= 0)
return {
...state,
}
//docker์ ํด๋น ์ดํ๋ฆฌ์ผ์ด์
์ด ์์ผ๋ฉด push
return {
...state,
docker: [...state.docker, action.data],
}
}
// filter๋ฅผ ํตํด ํด๋น ์ดํ๋ฆฌ์ผ์ด์
delete
case DOCKER_DELETE:
return {
...state,
docker: state.docker.filter((v, i) => action.data !== v),
}
default: {
return {
...state,
}
}
}
}
export const initialState = {
result: '0',
tempResult: '',
pressedOperator: '',
isFirstNumberTyping: true,
}
export const STORE_CALCULATOR_DATA = 'STORE_CALCULATOR_DATA'
export const STORE_RESET_CALCULATOR = 'STORE_RESET_CALCULATOR'
export default (state = initialState, action) => {
switch (action.type) {
// contentsMenubar ์์ ์ ์ฅ์ ํ์ผ๋ฉด ๋ฐ์ดํฐ ์ ์ฅ
case STORE_CALCULATOR_DATA: {
return {
result: action.data.result,
tempResult: action.data.tempResult,
pressedOperator: action.data.pressedOperator,
isFirstNumberTyping: action.data.isFirstNumberTyping,
}
}
// contentsMenubar์์ ๋ซ๊ธฐ๋ฅผ ํ์ผ๋ฉด ์ด๊ธฐ๋ฐ์ดํฐ๋ก ์ด๊ธฐํ
case STORE_RESET_CALCULATOR: {
return {
result: '0',
tempResult: '',
pressedOperator: '',
isFirstNumberTyping: false,
}
}
default: {
return {
...state,
}
}
}
}
์๋ฒ์ฌ์ด๋๋ ๋๋ง์ด ์์ง ์๋์๋ค.
๋ฐ์ํ ์์ง ์๋์๋ค.