
이번 글을 통해 배워갈 내용
- 리액트 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
300년차 개발자의 좋은 코드 5계명 (Clean Code)
이번 글을 통해 배워갈 내용 좋은 코드(Clean Code)를 작성하기 위해 개발자로서 생각해볼 5가지 요소를 알아보겠습니다. 개요 좋은 코드란 무엇일까요? 저는 자원이 한정적인 컴퓨터 세상에서 좋
codemasterkimc.tistory.com
728x90
'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 |