
오늘은 상태관리 라이브러리인 Zustand에 대해 이야기해보려고 합니다.
저희 회사에서는 따로 상태관리 라이브러리를 쓰지 않고 있어서, 실무에서 직접적으로 다룰 기회는 거의 없었어요.
그런데 최근 채용 공고를 살펴보다 보면, 대부분의 회사들이 상태관리 경험을 중요하게 보는 경우가 많더라구요.
특히 Redux, Recoil, Zustand 같은 키워드가 빠지지 않고 등장하는 걸 보면서 ‘나도 한번 제대로 공부해봐야겠다’는 생각이 들었습니다.
그래서 이번 기회에 Zustand를 직접 써보고, 기존에 많이 사용되는 Redux와는 어떻게 다른지 비교도 해봤어요.
생각보다 진입 장벽이 낮고, 코드가 간결해서 개인적으로는 꽤 만족스러웠는데요.
npm trend 사이트에서 보면,
최근에 Zustand의 사용량이 급격히 증가한 것을 확인할 수 있습니다.
현재는 Redux 다음으로 많이 사용되고 있는데,
기존에 대부분의 개발자들이 Redux를 주로 활용해왔다는 점을 고려하면 이 추세가 정말 인상적이라고 볼 수 있습니다.

또한 패키지 사이즈 측면에서도 정말 매력적인데요.
Zustand는 다른 상태관리 라이브러리에 비해 굉장히 가벼운 편이라 번들 크기에 거의 부담을 주지 않습니다.
실제로 설치해보면 "이게 진짜 상태관리 라이브러리 맞아?" 싶을 정도로 크기가 작아서,
프로젝트 성능 최적화를 신경 쓰는 분들에게 특히 매력적으로 다가옵니다.

사용 방법도 놀라울 만큼 간단합니다.
Zustand 공식 홈페이지에 들어가면 처음에 딱 보이는 코드 예제가 있는데,
처음 보면 “어..? 이거면 진짜 끝이야?” 싶을 정도로 간단하더라구요.
복잡한 설정이나 보일러플레이트 코드가 필요 없고, 그냥 몇 줄만 작성하면 바로 상태관리를 시작할 수 있습니다.
덕분에 처음 접하는 사람도 금방 이해할 수 있고,
Redux처럼 설정 단계에서부터 부담을 느낄 필요가 없다는 게 큰 장점이에요.

이 글에서는 Zustand의 특징과 사용법, 그리고 써보면서 느낀 장단점까지 솔직하게 정리해보려고 합니다.
Zustand 말고도 상태관리 라이브러리도 사실 꽤 많은 편인데요, 이번 포스팅에서는 zustand를 자세히 살펴보려고 해요.
다른 상태관리가 궁금하시다면 이전에 제가 정리해둔 포스트가 있으니 궁금하신 분들은 아래 글을 참고해주시면 좋을 것 같아요.
https://jjung2ing.tistory.com/81
[개발읽기 vol.5] 2025년 리액트 상태관리 가이드: Redux, Recoil, Zustand, Jotai, MobX 비교
요즘 채용 공고를 보면,자격요건이나 우대사항에 꼭 한 번쯤은 Redux, Zustand, MobX 같은 상태관리 라이브러리 이름이 등장합니다. 그만큼 리액트에서 상태관리를 어떻게 하느냐가 실무에서 중요한
jjung2ing.tistory.com
그리고 아마 "그럼 상태관리 라이브러리가 왜 필요하지?"라는 궁금증이 생기실 수도 있을 것 같아요.
그 이유는 기존 React의 상태 관리 방식 때문입니다.
React에서는 상태가 단방향으로만 흐르기 때문에, 다른 컴포넌트나 페이지와 상태를 공유하려면
상태를 상위 컴포넌트로 끌어올린 뒤 다시 하위 컴포넌트로 내려주는 방식으로 관리해야 하죠.
문제는 이 과정에서 끝도 없이 상태를 내려줘야 하는 이른바 Props Drilling 현상이 발생한다는 점입니다.
쉽게 비유하자면, 위쪽에서 물통을 받아 아래로 계속 전달해야 하는 상황과 비슷합니다.
중간에 하나라도 놓치면 물이 새듯, 상태를 잘못 전달하면 오류가 생기고, 코드는 점점 복잡해지며 유지보수에도 큰 부담을 주게 됩니다.
PropsDrilling
중첩된 컴포넌트간 상태고유를 위해 Props를 전달하는 과정에서 Props 전달이 드릴로 땅을 뚫듯 깊어지는 현상으로
유지보수가 어렵습니다.
- 중간에 props를 받기만 하는 컴포넌트가 많아지면 코드가 길어지고, 어떤 데이터가 어디서 왔는지 추적하기 어려워집니다.
- 예: App → A → B → C → D 구조에서 D에만 필요한 데이터라면 A, B, C는 단순 전달자 역할만 하게 됩니다.
컴포넌트 재사용성 감소
- 중간 컴포넌트들이 특정 props를 받아야 하므로, 재사용할 때 불필요한 props를 계속 전달해야 할 수도 있습니다.
리렌더링 문제
- 부모 컴포넌트가 리렌더링되면, props를 받는 모든 중간 컴포넌트가 함께 리렌더링될 수 있습니다.
- 성능 저하로 이어질 수 있습니다.
코드 가독성 저하
- 많은 계층을 거쳐 props가 전달되면 코드가 장황해지고, 데이터를 이해하고 수정하기 어려워집니다.
그럼 여기서 Zustand가 어떻게 Props Drilling 문제를 해결하는지 이야기해볼게요.
Zustand를 사용하면 상태를 중앙 저장소(store)에 보관할 수 있어서, 상위 컴포넌트로 끌어올리거나 하위로 내려줄 필요가 없습니다.
필요한 컴포넌트는 그냥 store에서 상태를 가져다 쓰면 되죠.
즉, 상태를 어디서든 쉽게 공유할 수 있고, 전달 과정에서 생기는 오류나 복잡함이 사라집니다.
게다가 Zustand는 사용법이 매우 간단합니다.
몇 줄의 코드로 store를 만들고, 원하는 컴포넌트에서 바로 상태를 읽거나 수정할 수 있죠.
Redux처럼 복잡한 액션, 리듀서, 미들웨어 설정이 필요 없어서, 작은 프로젝트나 개인 프로젝트에서도 부담 없이 바로 적용할 수 있습니다.
결과적으로 코드는 더 깔끔해지고 유지보수도 쉬워지며, 개발자가 상태 관리 때문에 고민할 시간도 줄일 수 있다는 장점이 있습니다.
🍎 Zustand
적은 보일러 플레이트 코드
직관적인 사용법
작은 패키지 사이즈
Flux처럼 단방향이지만 구조는 더 단순함
💡 용어정리
📝 보일러플레이트 코드(Boilerplate Code) : zustand는 보일러 플레이트 코드가 적다.
프로그램을 만들 때 반복적으로 꼭 작성해야 하는 기본 틀이나 코드를 말합니다.
예를 들어 Redux를 사용하면 상태를 관리하려고 할 때,
- 액션(action) 정의
- 리듀서(reducer) 작성
- 스토어(store) 설정
- 미들웨어(middleware) 적용
이런 과정들을 매번 비슷한 형태로 작성해야 하죠.
이처럼 실제 로직과 상관없이 구조상 꼭 필요한 반복 코드가 바로 보일러플레이트 코드입니다.
📝 Flux 패턴 : zustand는 Flux패턴 처럼 단방향이지만 구조는 더 단순하다.
데이터를 중앙 집중형 스토어에 저장하고 Action을 통해 데이터를 조작하는 패턴
Flux 패턴은 React 생태계에서 많이 쓰이는 상태 관리 구조 중 하나로,
애플리케이션의 상태(state)를 단방향으로 흐르게 설계하는 아키텍처입니다.
기본 구조는 다음과 같이 이해하면 쉽습니다.
- Action(액션)
- 상태를 변경하겠다는 의도를 담은 객체
- 예: ADD_TODO, REMOVE_ITEM
- Dispatcher(디스패처)
- Action을 받아서 Store로 전달하는 역할
- 중앙 허브 역할을 수행
- Store(스토어)
- 상태를 실제로 저장하고 관리
- 상태가 바뀌면 View에 알려서 화면을 갱신
- View(뷰)
- Store의 상태를 기반으로 UI를 렌더링
- 사용자가 UI를 통해 Action을 발생시킬 수 있음
즉, Flux는 Action → Dispatcher → Store → View 순으로
데이터가 한 방향으로만 흐르도록 설계되어 있어,
상태 관리가 예측 가능하고 복잡한 상태 변화를 추적하기 쉬운 구조를 제공합니다.
이건 WOOWACON에서 나온 내용인데, 이해하기 쉽게 나와있어서 가져와봤습니다.

자, 이제 Zustand를 실제로 어떻게 사용하는지 보여드릴게요.
공식 홈페이지에도 자세한 예시가 나와 있으니 참고하시면 좋습니다.
Zustand
zustand-demo.pmnd.rs
하지만 여기서도 간단히 설명해드릴게요.
1️⃣ 설치 방법
Zustand는 NPM 패키지로 제공되기 때문에, 프로젝트에 바로 설치해서 사용할 수 있습니다.
# NPM
npm install zustand
# Or, use any package manager of your choice.
2️⃣ 먼저 스토어(Store)를 만들어주세요
Zustand에서는 스토어가 훅(Hook)입니다.
스토어 안에는 원시값, 객체, 함수 등 원하는 무엇이든 넣을 수 있고,
set 함수를 사용하면 상태를 쉽게 업데이트할 수 있습니다.
import { create } from 'zustand'
const useStore = create((set) => ({
bears: 0,
increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
removeAllBears: () => set({ bears: 0 }),
updateBears: (newBears) => set({ bears: newBears }),
}))
3️⃣ 컴포넌트에서 스토어 사용하기
스토어 훅을 어디서든 사용할 수 있으며, Provider를 따로 쓸 필요가 없습니다.
스토어에서 상태를 선택(select)하면, 해당 상태가 변경될 때 컴포넌트가 자동으로 리렌더링 됩니다.
function BearCounter() {
const bears = useStore((state) => state.bears)
return <h1>{bears} bears around here...</h1>
}
function Controls() {
const increasePopulation = useStore((state) => state.increasePopulation)
return <button onClick={increasePopulation}>one up</button>
}
이렇게만 해도 상태 관리가 끝! 😄
간단하게 상태를 읽고 수정할 수 있으면서, 컴포넌트 간 공유도 아주 쉽게 할 수 있습니다.
🔍 비교: Zustand는 다른 상태관리 라이브러리와 어떻게 다른가?
Zustand는 React에서 사용할 수 있는 여러 상태관리 라이브러리 중 하나입니다.
이번 글에서는 Redux, Valtio, Jotai, Recoil 등과 비교하며 Zustand의 특징과 장단점을 살펴보겠습니다.
각 라이브러리는 저마다 장점과 단점이 있으며, 중요한 차이점과 공통점을 중심으로 비교합니다.
🟥 Redux와 비교
- 상태 모델(State Model)
개념적으로 Zustand와 Redux는 꽤 비슷합니다.
둘 다 불변(Immutable) 상태 모델을 기반으로 하고 있죠.
하지만 큰 차이점이 있습니다.- Redux는 앱 전체를 Context Provider로 감싸야 하는 반면,
- Zustand는 이런 설정이 필요 없고, 스토어 훅을 바로 사용할 수 있습니다.
Zustand
import { create } from 'zustand'
type State = {
count: number
}
type Actions = {
increment: (qty: number) => void
decrement: (qty: number) => void
}
const useCountStore = create<State & Actions>((set) => ({
count: 0,
increment: (qty: number) => set((state) => ({ count: state.count + qty })),
decrement: (qty: number) => set((state) => ({ count: state.count - qty })),
}))
- Zustand에서는 먼저 useCountStore라는 훅을 만들어 상태를 관리합니다.
이 스토어 안에는 count라는 상태와, 상태를 변경할 수 있는 increment와 decrement 같은 액션이 들어 있습니다.
상태를 업데이트할 때는 set 함수를 사용하면 되고, Redux처럼 별도의 리듀서나 미들웨어를 만들 필요 없이
단 몇 줄만으로 상태와 액션을 정의할 수 있어서 코드가 훨씬 간결합니다.
import { create } from 'zustand'
type State = {
count: number
}
type Actions = {
increment: (qty: number) => void
decrement: (qty: number) => void
}
type Action = {
type: keyof Actions
qty: number
}
const countReducer = (state: State, action: Action) => {
switch (action.type) {
case 'increment':
return { count: state.count + action.qty }
case 'decrement':
return { count: state.count - action.qty }
default:
return state
}
}
const useCountStore = create<State & Actions>((set) => ({
count: 0,
dispatch: (action: Action) => set((state) => countReducer(state, action)),
}))
- Zustand에서는 필요하다면 Redux처럼 리듀서 패턴도 적용할 수 있습니다.
이 경우, dispatch 함수를 통해 상태를 업데이트하며, 액션 타입과 상태를 변경하는 로직을 분리할 수 있죠.
즉, 구조는 Redux와 비슷하지만, 여전히 Provider 없이 훅만으로 바로 사용할 수 있다는 점이 큰 장점입니다.
Redux
import { createStore } from 'redux'
import { useSelector, useDispatch } from 'react-redux'
type State = {
count: number
}
type Action = {
type: 'increment' | 'decrement'
qty: number
}
const countReducer = (state: State, action: Action) => {
switch (action.type) {
case 'increment':
return { count: state.count + action.qty }
case 'decrement':
return { count: state.count - action.qty }
default:
return state
}
}
const countStore = createStore(countReducer)
- Redux는 상태 관리 구조가 Store와 Reducer로 명확하게 나뉘어 있습니다.
하지만 React에서 사용하려면 반드시 <Provider store={countStore}>로 앱 전체를 감싸야 합니다.
상태를 변경하려면 항상 dispatch를 통해서만 가능하며,
전체적으로 코드가 길고 반복되는 부분, 즉 boilerplate 코드가 많다는 단점이 있습니다.
import { createSlice, configureStore } from '@reduxjs/toolkit'
const countSlice = createSlice({
name: 'count',
initialState: { value: 0 },
reducers: {
incremented: (state, qty: number) => {
// Redux Toolkit does not mutate the state, it uses the Immer library
// behind scenes, allowing us to have something called "draft state".
state.value += qty
},
decremented: (state, qty: number) => {
state.value -= qty
},
},
})
const countStore = configureStore({ reducer: countSlice.reducer })
- Redux Toolkit은 Redux를 더 쉽게 사용할 수 있도록 만든 라이브러리입니다.
내부적으로 Immer 라이브러리를 사용하기 때문에, state.value += qty처럼 마치 상태를 직접 수정하는 것처럼 코드를 작성할 수 있습니다.
덕분에 반복되는 코드가 줄어들고, 타입스크립트와도 자연스럽게 통합되어 코드가 더 깔끔하고 가독성이 좋아집니다.
⚡ 렌더링 최적화(Render Optimization) – Redux와 비교
앱 내에서 렌더링 최적화를 고려할 때, Zustand와 Redux 간의 접근 방식에는 큰 차이가 없습니다.
두 라이브러리 모두 선택자(Selector)를 활용해 필요한 상태만 선택하고,
컴포넌트가 불필요하게 리렌더링되지 않도록 최적화를 적용하는 것이 권장됩니다.
즉, 상태 관리 라이브러리를 선택하더라도,
렌더링 성능을 높이려면 개발자가 직접 최적화를 신경 써야 한다는 점은 동일합니다.
Zustand
import { create } from 'zustand'
type State = {
count: number
}
type Actions = {
increment: (qty: number) => void
decrement: (qty: number) => void
}
const useCountStore = create<State & Actions>((set) => ({
count: 0,
increment: (qty: number) => set((state) => ({ count: state.count + qty })),
decrement: (qty: number) => set((state) => ({ count: state.count - qty })),
}))
const Component = () => {
const count = useCountStore((state) => state.count)
const increment = useCountStore((state) => state.increment)
const decrement = useCountStore((state) => state.decrement)
// ...
}
이 예제에서는 useCountStore라는 Zustand 스토어를 만들어 count 상태와 상태를 변경하는 함수들을 정의하고 있습니다.
- count라는 상태를 0으로 초기화하고,
- increment와 decrement라는 액션을 만들어 set 함수를 사용해 상태를 업데이트하도록 했습니다.
컴포넌트에서는 이 스토어 훅을 사용해 상태와 액션을 가져올 수 있습니다.
const count = useCountStore((state) => state.count)
const increment = useCountStore((state) => state.increment)
const decrement = useCountStore((state) => state.decrement)
즉, 필요한 상태나 액션만 선택해서 사용할 수 있고, 상태가 바뀌면 자동으로 해당 컴포넌트가 리렌더링됩니다.
이 방식의 장점은 Provider가 필요 없고, Redux처럼 복잡한 설정 없이 훅 하나로 상태 관리가 가능하다는 점입니다.
또한, 액션과 상태를 한 곳에서 정의할 수 있어 코드가 직관적이고 간결합니다.
Redux
import { createStore } from 'redux'
import { useSelector, useDispatch } from 'react-redux'
type State = {
count: number
}
type Action = {
type: 'increment' | 'decrement'
qty: number
}
const countReducer = (state: State, action: Action) => {
switch (action.type) {
case 'increment':
return { count: state.count + action.qty }
case 'decrement':
return { count: state.count - action.qty }
default:
return state
}
}
const countStore = createStore(countReducer)
const Component = () => {
const count = useSelector((state) => state.count)
const dispatch = useDispatch()
// ...
}
먼저 countReducer라는 리듀서 함수를 정의합니다.
- 상태 count를 가지고 있고,
- 액션 타입이 'increment'일 경우 count를 증가시키고,
- 'decrement'일 경우 count를 감소시킵니다.
- 그 외의 액션은 그대로 상태를 반환합니다.
const countStore = createStore(countReducer)
이렇게 리듀서를 전달해 스토어(Store)를 생성합니다.
Redux에서는 이 스토어를 앱 전체에 제공하기 위해 <Provider store={countStore}>로 감싸야 합니다.
컴포넌트에서는
const count = useSelector((state) => state.count)
const dispatch = useDispatch()
- useSelector를 사용해 상태를 읽고,
- useDispatch를 사용해 액션을 보내 상태를 업데이트합니다.
즉, Redux는 상태와 액션 관리가 명확하고 예측 가능하지만,
- 스토어와 Provider 설정, dispatch를 통한 상태 변경 등 코드가 상대적으로 길고 구조가 복잡하다는 특징이 있습니다.
import { useSelector } from 'react-redux'
import type { TypedUseSelectorHook } from 'react-redux'
import { createSlice, configureStore } from '@reduxjs/toolkit'
const countSlice = createSlice({
name: 'count',
initialState: { value: 0 },
reducers: {
incremented: (state, qty: number) => {
// Redux Toolkit does not mutate the state, it uses the Immer library
// behind scenes, allowing us to have something called "draft state".
state.value += qty
},
decremented: (state, qty: number) => {
state.value -= qty
},
},
})
const countStore = configureStore({ reducer: countSlice.reducer })
const useAppSelector: TypedUseSelectorHook<typeof countStore.getState> =
useSelector
const useAppDispatch: () => typeof countStore.dispatch = useDispatch
const Component = () => {
const count = useAppSelector((state) => state.count.value)
const dispatch = useAppDispatch()
// ...
}
먼저 createSlice를 이용해 상태와 액션을 한 번에 정의합니다.
- countSlice 안에는 상태 value가 있고,
- incremented와 decremented라는 액션이 정의되어 있습니다.
- Redux Toolkit은 내부적으로 Immer 라이브러리를 사용하기 때문에, state.value += qty처럼 마치 상태를 직접 변경하는 것처럼 작성해도 실제로는 불변성을 유지합니다.
const countStore = configureStore({ reducer: countSlice.reducer })
이렇게 스토어를 설정하고, 앱 전체에서 사용할 수 있도록 제공합니다.
컴포넌트에서는
const count = useAppSelector((state) => state.count.value)
const dispatch = useAppDispatch()
- useAppSelector를 통해 상태를 읽고,
- useAppDispatch로 액션을 디스패치해 상태를 업데이트합니다.
즉, Redux Toolkit은 기존 Redux보다 훨씬 간단하게 상태와 액션을 정의할 수 있고,
- 불변성을 직접 관리할 필요가 없어 코드를 더 깔끔하게 작성할 수 있다는 장점이 있습니다.

✅ 정리
- Zustand: 간단하고 직관적, 소규모/중규모 프로젝트에 적합
- Redux: 구조가 명확하고 예측 가능, 대규모 프로젝트에 유리하지만 boilerplate가 많음
- Redux Toolkit: Redux의 장점은 유지하면서 코드를 간결하게, Immer로 상태 변경이 편리
간단히 코드를 비교해 보자면,



⚠️ 상태관리 라이브러리는 무조건 써야 할까?
답변:
무조건 사용할 필요는 없습니다. 상태관리 라이브러리는 프로젝트 규모와 복잡도에 따라 선택하면 돼요.
💡 라이브러리가 필요할 때
- 🔹 여러 컴포넌트에서 같은 상태를 공유해야 할 때
- 🔹 상태 변화가 많고 복잡한 로직이 포함될 때
- 🔹 Props Drilling이 많아져 유지보수가 어려울 때
- 🔹 상태를 예측 가능하게 관리하고 싶을 때
⚡ 라이브러리가 필요 없을 때
- 🔹 상태 공유가 거의 없고 컴포넌트 내부 상태만 사용하는 작은 프로젝트
- 🔹 상태 변화가 단순해서 React의 useState나 useReducer만으로 충분할 때
✅ 정리
상태관리 라이브러리는 규모가 크거나 상태가 복잡한 앱에서 유용하지만,
작거나 단순한 프로젝트에서는 오히려 불필요한 학습과 코드 복잡도를 늘릴 수 있습니다.
실전에서 상태관리 라이브러리, 언제 쓰고 안 쓰나?
1️⃣ 사용하면 좋은 경우
- 앱 규모가 크고 여러 페이지나 컴포넌트에서 같은 상태를 공유해야 할 때
→ 예: 사용자 로그인 정보, 장바구니, 테마 설정 등 - 상태 변화가 많거나 복잡한 로직이 포함된 경우
→ 예: 계산 로직, 필터/정렬 기능, 동시성 상태 관리 - Props Drilling이 발생해 상위에서 하위로 상태를 계속 내려야 하는 구조가 반복될 때
- 상태를 예측 가능하게 관리하고 싶을 때
→ 팀 협업 시 버그 방지와 유지보수 용이
2️⃣ 사용하지 않아도 되는 경우
- 상태 공유가 거의 없고 컴포넌트 자체 상태만 사용하는 작은 프로젝트
→ 예: 단순 토글 버튼, 입력 폼, 작은 위젯 - 상태 변화가 단순해서 React의 useState나 useReducer로 충분할 때
- 라이브러리를 도입할 만큼 복잡도가 크지 않은 경우
오늘은 React 상태관리 라이브러리 중 Zustand, Redux, Redux Toolkit을 비교하며 살펴봤습니다.
각 라이브러리마다 장점과 단점이 명확하고, 사용 용도에 따라 적합한 선택이 달라집니다.
작고 단순한 프로젝트에서는 굳이 라이브러리를 도입하지 않아도 충분히 상태를 관리할 수 있고,
오히려 코드를 더 간결하게 유지할 수 있다는것을 알게되었습니다.
반대로 여러 컴포넌트가 상태를 공유하거나, 상태 변화가 복잡한 프로젝트에서는
Zustand처럼 직관적인 라이브러리나 Redux/Redux Toolkit을 활용하면 코드 유지보수가 훨씬 편리해짐을 알게 되었습니다.
Props Drilling을 피하고, 상태를 예측 가능하게 관리할 수 있다는 점도 큰 장점입니다.
상태관리 라이브러리는 도구일 뿐이며, 항상 프로젝트의 규모와 복잡도를 고려해서 선택하는 것이 중요합니다.
처음에는 작은 프로젝트에서 React 내장 훅으로 시작해보고, 필요할 때 점차 라이브러리를 도입하는 전략도 좋습니다.
오늘 소개한 내용이 상태관리 선택에 조금이라도 도움이 되었기를 바라며,
나중에는 실제 프로젝트에서 Zustand를 적용한 실전 예제와 팁을 공유해보겠습니다!
'개발 로그 > 오늘의 개발읽기' 카테고리의 다른 글
| [개발읽기 vol.10] 프론트엔드 개발자를 위한 Node.js와 npm 기초 완벽 정리 (1) | 2025.09.17 |
|---|---|
| [개발읽기 vol.9] 클라우드 아키텍처 진화: 모놀리식에서 MSA까지 완벽 정리 (1) | 2025.09.16 |
| [개발읽기 vol.7] 2025 최신 기업별 테크 블로그 모음 (1) | 2025.09.10 |
| [개발읽기 vol.6] 오픈소스 기여 방법 완벽 가이드 | 주니어·시니어 개발자가 얻는 이점 (0) | 2025.09.09 |
| [개발읽기 vol.5] 2025년 리액트 상태관리 가이드: Redux, Recoil, Zustand, Jotai, MobX 비교 (2) | 2025.09.08 |