반응형
이번 글을 통해 배워갈 내용
- 리액트 State를 관리하는 한 가지 방법
리액트를 다루면서 State가 많아지는 경우
Redux, Zustand 등의 상태 관리 라이브러리를 쓰기에는 애매모호한 경우들이 있습니다.
본 예제는
6개의 State = 과일 3개 + 채소 3개 해서
총 6개의 State를 2개의 리스트로 묶어서 사용합니다.
화면은 이와 같으며
일단 야채와 과일 리스트를 만들었습니다.
const fruitList = {
APPLE: 'apple',
BANANA: 'banana',
KIWI: 'kiwi'
}
const vegetableList = {
LETTUCE: 'lettuce ',
CABBAGE: 'cabbage ',
CARROT: 'carrot '
}
그다음 해당되는 State를 만들고 리스트를 수정해주는 함수도 만듭니다.
const [fruitState, _setFruitState] = useState({
[fruitList.APPLE]: 0,
[fruitList.BANANA]: 0,
[fruitList.KIWI]: 0,
})
const setFruitState = (fState) => {
const newVal = fState.val + 1
_setFruitState({ ...fruitState, [fState.key]: newVal })
}
const [vegetableState, _setVegetableState] = useState({
[vegetableList.LETTUCE]: 0,
[vegetableList.CABBAGE]: 0,
[vegetableList.CARROT]: 0,
})
const setVegetableState = (vState) => {
const newVal = vState.val + 1
_setVegetableState({ ...vegetableState, [vState.key]: newVal })
}
그다음 Virtual Dom을 만들어 줍니다.
return (
<StyleMarket>
<ul className='container'>
{/* Fruit list */}
{[
{ idx: 1, name: fruitList.APPLE, bg: '#EE4E2B' },
{ idx: 2, name: fruitList.BANANA, bg: '#FC7266' },
{ idx: 3, name: fruitList.KIWI, bg: '#D061FA' },
].map((item) => (
<li key={item.idx+item.name} onClick={()=>{setFruitState({key: item.name, val:fruitState[item.name]})}}className="fruit" style={{backgroundColor:item.bg}}><span>{item.name}</span><span>{fruitState[item.name]}</span></li>
))}
{/* Vege list */}
{[
{ idx: 1, name: vegetableList.LETTUCE, bg: '#2ECDFA' },
{ idx: 2, name: vegetableList.CABBAGE, bg: '#10CE84' },
{ idx: 3, name: vegetableList.CARROT, bg: 'rgb(204, 207, 173)' },
].map((item) => (
<li key={item.idx+item.name} onClick={()=>{setVegetableState({key: item.name, val:vegetableState[item.name]})}}className="vegetable" style={{backgroundColor:item.bg}}><span>{item.name}</span><span>{vegetableState[item.name]}</span></li>
))}
</ul>
</StyleMarket>
);
State를 묶어서 사용하기 때문에 가독성이 좋아지지만
성능이나 작업할 때 고민이 되는 부분이 있습니다.
컴포넌트의 전체 코드는 아래와 같습니다.
(Styled Component 사용)
import React, { useState } from "react";
import styled from 'styled-components';
// Styled Components
const StyleMarket = styled.div`
& {
width: 100vw;
height: 100vh;
background: #0f2027; /* fallback for old browsers */
background: -webkit-linear-gradient(to right, #2c5364, #203a43, #0f2027); /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #2c5364, #203a43, #0f2027); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
}
& .container {
padding: 0;
position: fixed;
top: calc(50% - 220px / 2);
left: calc(50% - 320px / 2);
display: grid;
width: 320px;
height: 220px;
grid-template-rows: repeat(3,100px);
grid-template-columns: repeat(3,100px);
gap: 10px;
border-radius: 20px;
box-shadow: 0 28px 28px rgba(0, 0, 0, 0.2);
}
& .container li{
color: #fff;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
`
// React Components
const Test = () => {
const fruitList = {
APPLE: 'apple',
BANANA: 'banana',
KIWI: 'kiwi'
}
const vegetableList = {
LETTUCE: 'lettuce ',
CABBAGE: 'cabbage ',
CARROT: 'carrot '
}
const [fruitState, _setFruitState] = useState({
[fruitList.APPLE]: 0,
[fruitList.BANANA]: 0,
[fruitList.KIWI]: 0,
})
const setFruitState = (fState) => {
const newVal = fState.val + 1
_setFruitState({ ...fruitState, [fState.key]: newVal })
}
const [vegetableState, _setVegetableState] = useState({
[vegetableList.LETTUCE]: 0,
[vegetableList.CABBAGE]: 0,
[vegetableList.CARROT]: 0,
})
const setVegetableState = (vState) => {
const newVal = vState.val + 1
_setVegetableState({ ...vegetableState, [vState.key]: newVal })
}
return (
<StyleMarket>
<ul className='container'>
{/* Fruit list */}
{[
{ idx: 1, name: fruitList.APPLE, bg: '#EE4E2B' },
{ idx: 2, name: fruitList.BANANA, bg: '#FC7266' },
{ idx: 3, name: fruitList.KIWI, bg: '#D061FA' },
].map((item) => (
<li key={item.idx+item.name} onClick={()=>{setFruitState({key: item.name, val:fruitState[item.name]})}}className="fruit" style={{backgroundColor:item.bg}}><span>{item.name}</span><span>{fruitState[item.name]}</span></li>
))}
{/* Vege list */}
{[
{ idx: 1, name: vegetableList.LETTUCE, bg: '#2ECDFA' },
{ idx: 2, name: vegetableList.CABBAGE, bg: '#10CE84' },
{ idx: 3, name: vegetableList.CARROT, bg: 'rgb(204, 207, 173)' },
].map((item) => (
<li key={item.idx+item.name} onClick={()=>{setVegetableState({key: item.name, val:vegetableState[item.name]})}}className="vegetable" style={{backgroundColor:item.bg}}><span>{item.name}</span><span>{vegetableState[item.name]}</span></li>
))}
</ul>
</StyleMarket>
);
}
export default Test
출처 및 인용
김씨
https://codemasterkimc.tistory.com/50
반응형
'Javascript > React' 카테고리의 다른 글
리액트에서 여러 체크박스들을 하나의 컴포넌트로 재활용 해보기 ts (0) | 2022.06.22 |
---|---|
김씨가 리액트에서 함수 활용하는 비법 한가지 (0) | 2022.05.31 |
리액트 SVG로 손글씨 그림그리기 효과 구현해보는 한가지 방법 (0) | 2022.03.12 |
리액트 훅으로 생성자 구현해보는 1가지 방법 (0) | 2022.03.06 |
리액트 훅을 이용해 카메라 CSS 제작 및 촬영 기능 추가하는 한가지 방법 (0) | 2022.03.01 |