Skip to content

Commit 0e7da8d

Browse files
authored
Making sure models created with useLocalStore stop updating the state on update (#914)
Co-authored-by: Anton Zhuravsky <anton@44pixels.ai>
1 parent 0bbc885 commit 0e7da8d

2 files changed

Lines changed: 51 additions & 2 deletions

File tree

src/use-local-store.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export function useLocalStore(
2828

2929
useEffect(() => {
3030
setCurrentState(store.getState());
31-
store.subscribe(() => {
31+
return store.subscribe(() => {
3232
const nextState = store.getState();
3333
if (currentState !== nextState) {
3434
setCurrentState(nextState);

tests/use-local-store.test.js

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { render, fireEvent } from '@testing-library/react';
2+
import { render, fireEvent, act } from '@testing-library/react';
33
import { useLocalStore, action } from '../src';
44

55
function CountDisplay() {
@@ -300,3 +300,52 @@ test('updates the store if a dependency changes', () => {
300300
count: 200,
301301
});
302302
});
303+
304+
test('stops propagating state update when dependencies change', () => {
305+
// ARRANGE
306+
let currentState;
307+
let currentActions;
308+
309+
// eslint-disable-next-line no-shadow, react/prop-types
310+
function CountDisplay({ version }) {
311+
[currentState, currentActions] = useLocalStore(() => ({
312+
count: 0,
313+
up: action((state) => {
314+
state.count = 137;
315+
})
316+
}), [version]);
317+
return null;
318+
}
319+
320+
// ACT
321+
const { rerender } = render(<CountDisplay version={1} />);
322+
323+
// capture action from *current* model instance
324+
const {up} = currentActions;
325+
326+
// ASSERT
327+
expect(currentState).toEqual({
328+
count: 0,
329+
});
330+
331+
// ACT
332+
rerender(<CountDisplay version={2} />);
333+
334+
// ASSERT
335+
expect(currentState).toEqual({
336+
count: 0,
337+
});
338+
339+
// invoke "old" action – since we re-rendered the model it should be no-op
340+
act(() => {
341+
up();
342+
});
343+
344+
// ACT
345+
rerender(<CountDisplay version={2} />);
346+
347+
// ASSERT
348+
expect(currentState).toEqual({
349+
count: 0,
350+
});
351+
});

0 commit comments

Comments
 (0)