Skip to content

Commit ccc9432

Browse files
BREAKING CHANGE(@focus-js/react-connect): useGlobalState and useFocusedState return an array instead of an object.
1 parent a029176 commit ccc9432

File tree

4 files changed

+29
-39
lines changed

4 files changed

+29
-39
lines changed

README.md

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# @focus-js/react-connect
2+
13
A lens-based state manager. Library/Framework agnostic. Connector for React.
24

35
## Table of Contents
@@ -49,22 +51,18 @@ const { useFocusedState } = connect<ApplicationState>({
4951
b: 0,
5052
});
5153

52-
const lens = createLens<ApplicationState, number>({
54+
const a_lens = createLens<ApplicationState, number>({
5355
get: ({ a }) => a,
5456
set: (state, a) => ({ ...state, a }),
5557
});
5658

5759
const CounterA: React.FunctionComponent = () => {
58-
const { state, updateState } = useFocusedState(lens);
59-
60-
const increment = (): void => {
61-
updateState((n) => n + 1);
62-
};
60+
const [counter, increment] = useFocusedState(a_lens);
6361

6462
return (
6563
<div>
66-
<div>{state}</div>
67-
<button onClick={increment}>Increment</button>
64+
<div>{counter}</div>
65+
<button onClick={() => increment((n) => n + 1)}>Increment</button>
6866
</div>
6967
);
7068
};
@@ -589,9 +587,7 @@ With this setup:
589587
Once your lenses are defined in this centralized way, you can use them anywhere in your application to both read and update state with minimal boilerplate. For example, accessing and updating the rank of project `"project-3"` is as simple as:
590588

591589
```typescript
592-
const { state: rank, updateState: updateRank } = useFocusedState(
593-
L.rank('project-3')
594-
);
590+
const [rank, updateRank] = useFocusedState(L.rank('project-3'));
595591
```
596592

597593
Here, `rank` contains the current value (`number`) and `updateRank` lets you apply reducers directly to that piece of state. For instance, incrementing the rank becomes trivial:

packages/react-connect/README.md

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,18 @@ const { useFocusedState } = connect<ApplicationState>({
5151
b: 0,
5252
});
5353

54-
const lens = createLens<ApplicationState, number>({
54+
const a_lens = createLens<ApplicationState, number>({
5555
get: ({ a }) => a,
5656
set: (state, a) => ({ ...state, a }),
5757
});
5858

5959
const CounterA: React.FunctionComponent = () => {
60-
const { state, updateState } = useFocusedState(lens);
61-
62-
const increment = (): void => {
63-
updateState((n) => n + 1);
64-
};
60+
const [counter, increment] = useFocusedState(a_lens);
6561

6662
return (
6763
<div>
68-
<div>{state}</div>
69-
<button onClick={increment}>Increment</button>
64+
<div>{counter}</div>
65+
<button onClick={() => increment((n) => n + 1)}>Increment</button>
7066
</div>
7167
);
7268
};
@@ -591,9 +587,7 @@ With this setup:
591587
Once your lenses are defined in this centralized way, you can use them anywhere in your application to both read and update state with minimal boilerplate. For example, accessing and updating the rank of project `"project-3"` is as simple as:
592588

593589
```typescript
594-
const { state: rank, updateState: updateRank } = useFocusedState(
595-
L.rank('project-3')
596-
);
590+
const [rank, updateRank] = useFocusedState(L.rank('project-3'));
597591
```
598592

599593
Here, `rank` contains the current value (`number`) and `updateRank` lets you apply reducers directly to that piece of state. For instance, incrementing the rank becomes trivial:

packages/react-connect/src/lib/index.spec.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ describe('Without focusing', () => {
1212

1313
test('It should allow to read the state', async () => {
1414
// Given
15-
const { useGlobalState: useState } = connect<State>(0);
15+
const { useGlobalState } = connect<State>(0);
1616

1717
const Component: React.FunctionComponent = () => {
18-
const { state, updateState } = useState();
18+
const [state, updateState] = useGlobalState();
1919

2020
const onClick = (): void => {
2121
updateState((state) => state + 1);
@@ -40,10 +40,10 @@ describe('Without focusing', () => {
4040

4141
test('It should allow to update the state', async () => {
4242
// Given
43-
const { useGlobalState: useState } = connect<State>(0);
43+
const { useGlobalState } = connect<State>(0);
4444

4545
const Component: React.FunctionComponent = () => {
46-
const { state, updateState } = useState();
46+
const [state, updateState] = useGlobalState();
4747

4848
const onClick = (): void => {
4949
updateState((state) => state + 1);
@@ -82,13 +82,13 @@ describe('With focusing', () => {
8282

8383
test('It should allow to read the state', async () => {
8484
// Given
85-
const { useFocusedState: useState } = connect<State>({
85+
const { useFocusedState } = connect<State>({
8686
value: 0,
8787
other: 'other',
8888
});
8989

9090
const Component: React.FunctionComponent = () => {
91-
const { state, updateState } = useState(lens);
91+
const [state, updateState] = useFocusedState(lens);
9292

9393
const onClick = (): void => {
9494
updateState((state) => state + 1);
@@ -113,13 +113,13 @@ describe('With focusing', () => {
113113

114114
test('It should allow to update the state', async () => {
115115
// Given
116-
const { useFocusedState: useState } = connect<State>({
116+
const { useFocusedState } = connect<State>({
117117
value: 0,
118118
other: 'other',
119119
});
120120

121121
const Component: React.FunctionComponent = () => {
122-
const { state, updateState } = useState(lens);
122+
const [state, updateState] = useFocusedState(lens);
123123

124124
const onClick = (): void => {
125125
updateState((state) => state + 1);
@@ -163,10 +163,10 @@ describe('Change detection', () => {
163163

164164
test('A should update without B to render', async () => {
165165
// Given
166-
const { useFocusedState: useState } = connect<State>({ a: 0, b: 0 });
166+
const { useFocusedState } = connect<State>({ a: 0, b: 0 });
167167

168168
const A: React.FunctionComponent = () => {
169-
const { state, updateState } = useState(aLens);
169+
const [state, updateState] = useFocusedState(aLens);
170170

171171
const onClick = (): void => {
172172
updateState((state) => state + 1);
@@ -185,7 +185,7 @@ describe('Change detection', () => {
185185
const bSpy = vi.fn();
186186

187187
const B: React.FunctionComponent = () => {
188-
const { state } = useState(bLens);
188+
const [state] = useFocusedState(bLens);
189189

190190
React.useEffect(() => {
191191
bSpy();

packages/react-connect/src/lib/index.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@ export const connect = <State>(initialState: State, logger: Logger = noop) => {
1414
const useFocusedState = <Focus = State>(lens: Lens<State, Focus>) => {
1515
const focusedStore = store.focus(lens);
1616

17-
const { subscribe, getState, select, updateState } = focusedStore;
17+
const { getState, updateState, select, subscribe } = focusedStore;
1818

1919
const state = useSyncExternalStore(subscribe, getState);
2020

21-
return {
22-
state,
23-
getSynchronousState: getState,
24-
select,
21+
return [
22+
state, // reactive state
2523
updateState,
26-
};
24+
select,
25+
getState, // synchronous state
26+
] as const;
2727
};
2828

2929
const NOOP_LENS = createLens<State, State>({

0 commit comments

Comments
 (0)