Skip to content

Commit

Permalink
fix: useSet should stable (#129)
Browse files Browse the repository at this point in the history
  • Loading branch information
yc-kanyun authored Jan 15, 2025
1 parent fd58850 commit de57ac4
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
5 changes: 5 additions & 0 deletions .changeset/ninety-deers-nail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'ccstate-react': minor
---

fix: useSet should useCallback to keep stable
32 changes: 32 additions & 0 deletions packages/react/src/__tests__/get-and-set.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 +260,35 @@ describe('react', () => {
expect(store.getSubscribeGraph()).toHaveLength(0);
});
});

it('useSet should be stable', () => {
const count$ = state(0);

function Container() {
const count = useGet(count$);
return <Foo count={count} />;
}

function Foo({ count }: { count: number }) {
const setCount = useSet(count$);

return (
<>
count: {count}
<RenderCounter setCount={setCount} />
</>
);
}

const trace = vi.fn();
function RenderCounter({ setCount }: { setCount: (val: number) => void }) {
trace(setCount);
setCount(1);
return <div>Render</div>;
}

render(<Container />);

expect(trace).toHaveBeenCalledTimes(2);
expect(trace.mock.calls[0][0]).toBe(trace.mock.calls[1][0]);
});
22 changes: 11 additions & 11 deletions packages/react/src/useSet.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useCallback } from 'react';
import { useStore } from './provider';
import type { Command, State, StateArg } from 'ccstate';

Expand All @@ -13,15 +14,14 @@ export function useSet<T, CommandArgs extends unknown[]>(
): ValueSetter<T> | CommandInvoker<T, CommandArgs> {
const store = useStore();

if ('write' in signal) {
return (...args: CommandArgs): T => {
const ret = store.set(signal, ...args);

return ret;
};
}

return (value: StateArg<T>) => {
store.set(signal, value);
};
return useCallback(
'write' in signal
? (...args: CommandArgs): T => {
return store.set(signal, ...args);
}
: (value: StateArg<T>) => {
store.set(signal, value);
},
[store, signal],
);
}

0 comments on commit de57ac4

Please sign in to comment.