Skip to content

Commit 2e3d55a

Browse files
committed
feat: add setter hook
1 parent 7a95535 commit 2e3d55a

File tree

10 files changed

+140
-161
lines changed

10 files changed

+140
-161
lines changed

.github/workflows/publish.yml

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ jobs:
3737
uses: actions/setup-node@v4
3838
with:
3939
node-version: '18'
40-
registry-url: 'https://npm.pkg.github.com'
41-
scope: '@context-query'
4240

4341
- name: Install pnpm
4442
uses: pnpm/action-setup@v2
@@ -75,27 +73,18 @@ jobs:
7573
echo "Updated version to ${{ github.event.inputs.version }}"
7674
7775
- name: Build package
78-
run: |
79-
cd packages/${{ github.event.inputs.package }}
80-
pnpm run build
76+
run: pnpm build --filter=@context-query/${{ github.event.inputs.package }}
8177

82-
- name: Configure npm authentication
83-
run: |
84-
echo "@context-query:registry=https://npm.pkg.github.com" >> ~/.npmrc
85-
echo "//npm.pkg.github.com/:_authToken=${{ secrets.PACKAGE_KEY }}" >> ~/.npmrc
86-
87-
- name: Publish to GitHub Packages
78+
- name: Publish to npm Registry
8879
run: |
8980
cd packages/${{ github.event.inputs.package }}
9081
if [[ "${{ github.event.inputs.prerelease }}" == "true" ]]; then
91-
npm publish --tag prerelease
82+
npm publish --tag prerelease --registry=https://registry.npmjs.org --//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}
9283
echo "Published as prerelease with tag 'prerelease'"
9384
else
94-
npm publish
85+
npm publish --registry=https://registry.npmjs.org --//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}
9586
echo "Published as latest"
9687
fi
97-
env:
98-
NODE_AUTH_TOKEN: ${{ secrets.PACKAGE_KEY }}
9988
10089
- name: Commit version change
10190
if: github.event.inputs.prerelease == 'false'
@@ -125,7 +114,7 @@ jobs:
125114
body: |
126115
## @context-query/${{ github.event.inputs.package }} v${{ github.event.inputs.version }}
127116
128-
Published to GitHub Packages.
117+
Published to npm registry.
129118
130119
### Installation
131120
```bash

packages/playground/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"preview": "vite preview"
1010
},
1111
"dependencies": {
12-
"@context-query/react": "0.2.1",
12+
"@context-query/react": "0.3.1-beta.1",
1313
"@radix-ui/react-slot": "^1.1.2",
1414
"@tailwindcss/vite": "^4.0.13",
1515
"class-variance-authority": "^0.7.1",

packages/playground/src/ContextQueryImplementation.tsx

Lines changed: 36 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import { useEffect } from "react";
22
import { Button } from "./components/ui/button";
33
import {
44
CounterQueryProvider,
5-
setCounterState,
6-
updateCounterState,
75
useCounterQuery,
6+
useCounterSetter,
87
} from "./CounterContextQueryProvider";
98
import { cqLogger } from "./LoggerInstance";
109

1110
function CQCounter3() {
12-
const [{ count3 }, setState] = useCounterQuery(["count3"]);
11+
const [{ count3 }] = useCounterQuery(["count3"]);
12+
const setState = useCounterSetter();
1313

1414
useEffect(() => {
1515
cqLogger.log(`Counter3 컴포넌트 렌더링 - ${count3}`);
@@ -24,7 +24,7 @@ function CQCounter3() {
2424
};
2525

2626
const reset = () => {
27-
setState({ count3: 0 });
27+
setState((prev) => ({ ...prev, count3: 0 }));
2828
};
2929

3030
return (
@@ -51,22 +51,27 @@ function CQCounter3() {
5151
}
5252

5353
function CQCounter2() {
54-
const [{ count2 }, setState] = useCounterQuery(["count2"]);
54+
const [{ count2 }] = useCounterQuery(["count2"]);
55+
const setState = useCounterSetter();
5556

5657
useEffect(() => {
5758
cqLogger.log(`Counter2 컴포넌트 렌더링 - ${count2}`);
5859
});
5960

6061
const increment = () => {
61-
setState((prev) => ({ ...prev, count2: prev.count2 + 1 }));
62+
setState((prev) => ({
63+
...prev,
64+
count2: prev.count2 + 1,
65+
count3: prev.count3 + 1
66+
}));
6267
};
6368

6469
const decrement = () => {
6570
setState((prev) => ({ ...prev, count2: prev.count2 - 1 }));
6671
};
6772

6873
const reset = () => {
69-
setState({ count2: 0 });
74+
setState((prev) => ({ ...prev, count2: 0 }));
7075
};
7176

7277
return (
@@ -95,22 +100,39 @@ function CQCounter2() {
95100
}
96101

97102
const CQCounter1 = () => {
98-
const [state, setState] = useCounterQuery(["count1", "count2"]);
103+
// count1만 구독하여 리렌더링 대상으로 설정
104+
const [{ count1 }] = useCounterQuery(["count1"]);
105+
106+
// 전체 상태 업데이트용 setter
107+
const setState = useCounterSetter();
99108

100109
useEffect(() => {
101-
cqLogger.log(`Counter1 컴포넌트 렌더링 - ${state.count1} ${state.count2}`);
110+
cqLogger.log(`Counter1 컴포넌트 렌더링 - ${count1}`);
102111
});
103112

104113
const increment = () => {
105-
setState((prev) => ({ count1: prev.count1 + 1, count2: prev.count2 + 1 }));
114+
// 전체 상태를 한번에 업데이트
115+
setState((prev) => ({
116+
count1: prev.count1 + 1,
117+
count2: prev.count2 + 1,
118+
count3: prev.count3 + 1
119+
}));
106120
};
107121

108122
const decrement = () => {
109-
setState((prev) => ({ count1: prev.count1 - 1, count2: prev.count2 - 1 }));
123+
setState((prev) => ({
124+
count1: prev.count1 - 1,
125+
count2: prev.count2 - 1,
126+
count3: prev.count3 - 1
127+
}));
110128
};
111129

112130
const reset = () => {
113-
setState({ count1: 0, count2: 0 });
131+
setState({
132+
count1: 0,
133+
count2: 0,
134+
count3: 0
135+
});
114136
};
115137

116138
return (
@@ -120,7 +142,7 @@ const CQCounter1 = () => {
120142
<h2 className="text-lg font-semibold">카운터 1</h2>
121143
<div className="flex items-center justify-between gap-4">
122144
<span className="text-2xl font-bold text-blue-600">
123-
{state.count1},{state.count2}
145+
{count1}
124146
</span>
125147
<div className="flex gap-2">
126148
<Button size="sm" variant="outline" onClick={decrement}>
@@ -141,35 +163,9 @@ const CQCounter1 = () => {
141163
};
142164

143165
export function ContextQueryImplementation() {
144-
const incrementCount1 = () => {
145-
setCounterState("count1", (prev) => prev + 1);
146-
};
147-
148-
const incrementCount2 = () => {
149-
setCounterState("count2", (prev) => prev + 1);
150-
};
151-
152-
const incrementCount3 = () => {
153-
setCounterState("count3", (prev) => prev + 1);
154-
};
155-
156-
const incrementAllCounts = () => {
157-
updateCounterState((state) => ({
158-
count1: state.count1 + 1,
159-
count2: state.count2 + 1,
160-
count3: state.count3 + 1,
161-
}));
162-
};
163-
164166
return (
165167
<div>
166-
<div className="flex justify-center space-x-4 mt-4 mb-4">
167-
<Button onClick={incrementCount1}>count1 증가</Button>
168-
<Button onClick={incrementCount2}>count2 증가</Button>
169-
<Button onClick={incrementCount3}>count3 증가</Button>
170-
<Button onClick={incrementAllCounts}>전체 증가</Button>
171-
</div>
172-
<CounterQueryProvider>
168+
<CounterQueryProvider initialState={{ count1: 0, count2: 0, count3: 0 }}>
173169
<div className="rounded-lg bg-card text-card-foreground shadow-sm p-4">
174170
<h2 className="text-xl font-bold mb-2">Context Query 버전</h2>
175171
<p className="text-muted-foreground mb-4">
@@ -180,91 +176,9 @@ export function ContextQueryImplementation() {
180176
<CQCounter1 />
181177
<CQCounter2 />
182178
<CQCounter3 />
183-
<AllStateSub />
184179
</div>
185-
186-
<BatchCounterControls />
187180
</div>
188181
</CounterQueryProvider>
189182
</div>
190183
);
191184
}
192-
193-
// 새로운 컴포넌트 추가: 일괄 처리 컨트롤
194-
function BatchCounterControls() {
195-
useEffect(() => {
196-
cqLogger.log("BatchCounterControls 컴포넌트 렌더링");
197-
});
198-
199-
const incrementAll = () => {
200-
updateCounterState((state) => ({
201-
count1: state.count1 + 1,
202-
count2: state.count2 + 1,
203-
count3: state.count3 + 1,
204-
}));
205-
};
206-
207-
const decrementAll = () => {
208-
updateCounterState((state) => ({
209-
count1: state.count1 - 1,
210-
count2: state.count2 - 1,
211-
count3: state.count3 - 1,
212-
}));
213-
};
214-
215-
const resetAll = () => {
216-
updateCounterState(() => ({
217-
count1: 0,
218-
count2: 0,
219-
count3: 0,
220-
}));
221-
};
222-
223-
const multiplyAll = () => {
224-
updateCounterState((state) => ({
225-
count1: state.count1 * 2,
226-
count2: state.count2 * 2,
227-
count3: state.count3 * 2,
228-
}));
229-
};
230-
231-
return (
232-
<div className="rounded-lg bg-card text-card-foreground shadow-sm mt-6 p-4 border-2 border-dashed border-purple-300">
233-
<h2 className="text-lg font-semibold mb-3">일괄 처리 컨트롤</h2>
234-
<p className="text-sm text-muted-foreground mb-4">
235-
모든 카운터를 한 번에 업데이트합니다
236-
</p>
237-
<div className="flex gap-2 flex-wrap">
238-
<Button onClick={incrementAll} variant="default">
239-
모두 증가
240-
</Button>
241-
<Button onClick={decrementAll} variant="outline">
242-
모두 감소
243-
</Button>
244-
<Button onClick={resetAll} variant="secondary">
245-
모두 초기화
246-
</Button>
247-
<Button onClick={multiplyAll} variant="destructive">
248-
모두 2배
249-
</Button>
250-
</div>
251-
</div>
252-
);
253-
}
254-
255-
function AllStateSub() {
256-
const [state] = useCounterQuery();
257-
258-
useEffect(() => {
259-
cqLogger.log("AllStateSub 컴포넌트 렌더링");
260-
});
261-
262-
return (
263-
<div>
264-
<h2>AllStateSub</h2>
265-
<p>{state.count1}</p>
266-
<p>{state.count2}</p>
267-
<p>{state.count3}</p>
268-
</div>
269-
);
270-
}
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { createContextQuery } from "@context-query/react";
22

33
export const {
4-
Provider: CounterQueryProvider,
4+
ContextQueryProvider: CounterQueryProvider,
55
useContextQuery: useCounterQuery,
6-
updateState: updateCounterState,
7-
setState: setCounterState,
8-
} = createContextQuery({ count1: 0, count2: 0, count3: 0 });
6+
useContextSetter: useCounterSetter,
7+
} = createContextQuery();

packages/playground/src/ReactContextImplementation.tsx

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { rcLogger } from "./LoggerInstance";
44
import {
55
ReactCounterProvider,
66
useReactCounterState,
7+
useReactCounterFullState,
78
} from "./ReactContextProvider";
89

910
function RCCounter3() {
@@ -50,13 +51,18 @@ function RCCounter3() {
5051

5152
function RCCounter2() {
5253
const [state, setState] = useReactCounterState("count2");
54+
const [, , setFullState] = useReactCounterFullState();
5355

5456
useEffect(() => {
5557
rcLogger.log(`Counter2 컴포넌트 렌더링 - ${state}`);
5658
});
5759

5860
const increment = () => {
59-
setState(state + 1);
61+
setFullState((prev) => ({
62+
...prev,
63+
count2: prev.count2 + 1,
64+
count3: prev.count3 + 1
65+
}));
6066
};
6167

6268
const decrement = () => {
@@ -94,21 +100,34 @@ function RCCounter2() {
94100

95101
function RCCounter1() {
96102
const [state, setState] = useReactCounterState("count1");
103+
const [, , setFullState] = useReactCounterFullState();
97104

98105
useEffect(() => {
99106
rcLogger.log(`Counter1 컴포넌트 렌더링 - ${state}`);
100107
});
101108

102109
const increment = () => {
103-
setState(state + 1);
110+
setFullState((prev) => ({
111+
count1: prev.count1 + 1,
112+
count2: prev.count2 + 1,
113+
count3: prev.count3 + 1
114+
}));
104115
};
105116

106117
const decrement = () => {
107-
setState(state - 1);
118+
setFullState((prev) => ({
119+
count1: prev.count1 - 1,
120+
count2: prev.count2 - 1,
121+
count3: prev.count3 - 1
122+
}));
108123
};
109124

110125
const reset = () => {
111-
setState(0);
126+
setFullState(() => ({
127+
count1: 0,
128+
count2: 0,
129+
count3: 0
130+
}));
112131
};
113132

114133
return (

0 commit comments

Comments
 (0)