Skip to content

Commit

Permalink
feat(api): add getStore to Lane apis
Browse files Browse the repository at this point in the history
  • Loading branch information
ArrayZoneYour committed Feb 20, 2022
1 parent b7ee895 commit 19e9ea0
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 3 deletions.
34 changes: 34 additions & 0 deletions __test__/lane/lane.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,40 @@ describe('lane model', () => {
})
})

test('use getStore outside react lifecycle', async () => {
const { useStore, getStore } = createStore(() => {
const [count, setCount] = useModel(1)
return { count, setCount }
})
let renderTimes = 0

act(() => {
expect(getStore()).toEqual(undefined)
})

const { result } = renderHook(() => {
const { count, setCount } = useStore()
renderTimes += 1
return { renderTimes, count, setCount }
})

act(() => {
expect(result.current.renderTimes).toEqual(1)
expect(result.current.count).toBe(1)
expect(getStore()?.count).toBe(1)
})

act(() => {
result.current.setCount(5)
})

act(() => {
expect(renderTimes).toEqual(2)
expect(result.current.count).toBe(5)
expect(getStore()?.count).toBe(5)
})
})

test('multiple models', async () => {
const { useStore } = createStore(() => {
const [count, setCount] = useModel(1)
Expand Down
43 changes: 43 additions & 0 deletions __test__/lane/react.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,49 @@ describe('compatible with useState + useEffect', () => {
})
})

test('getStore with useEffect inside FC', async () => {
const useCount = () => {
const [count, setCount] = useState(1)
return { count, setCount }
}
const { useStore, getStore } = createStore(useCount)
let renderTimes = 0
let validEffectTimes = 0
const { result } = renderHook(() => {
const { count: lastCount } = getStore() || { count: undefined }
const { count, setCount } = useStore()
useEffect(() => {
const { count: cachedCount } = getStore() || { count: undefined }
console.error(lastCount, ' ', count, ' ', cachedCount)
if (cachedCount === count && count !== lastCount) {
validEffectTimes += 1
}
})
renderTimes += 1
console.error('validEffectTimes: ', validEffectTimes)
return { renderTimes, count, setCount, validEffectTimes }
})
act(() => {
expect(result.current.renderTimes).toEqual(1)
expect(validEffectTimes).toEqual(1)
// effect is next tick
expect(result.current.validEffectTimes).toEqual(0)
expect(result.current.count).toBe(1)
})

act(() => {
result.current.setCount(5)
})

act(() => {
expect(renderTimes).toEqual(2)
expect(validEffectTimes).toEqual(2)
// effect is next tick
expect(result.current.validEffectTimes).toEqual(1)
expect(result.current.count).toBe(5)
})
})

test('combine useState and useStore', async () => {
const useCount = () => {
// useState create local state
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-model",
"version": "4.2.1-rc.0",
"version": "4.3.0-alpha.1",
"description": "The State management library for React",
"main": "./dist/react-model.js",
"module": "./dist/react-model.esm.js",
Expand Down
1 change: 1 addition & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ interface API<MT extends ModelType = ModelType<any, any, {}>> {
interface LaneAPI<S> {
useStore: () => S
getState: () => S
getStore: () => S | undefined
subscribe: (callback: () => void) => void
unsubscribe: (callback: () => void) => void
}
Expand Down
5 changes: 3 additions & 2 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,15 @@ function createStore<S>(n: any, u?: any): LaneAPI<S> {
const selector = () => {
Global.mutableState[storeId].count = 0
Global.currentStoreId = storeId
const res = u ? u() : n()
return res
Global.mutableState[storeId].cachedResult = u ? u() : n()
return Global.mutableState[storeId].cachedResult
}
Global.mutableState[storeId].selector = selector
return {
// TODO: support selector
useStore: () => useStore(storeId, selector),
getState: () => selector(),
getStore: () => Global.mutableState[storeId].cachedResult,
subscribe: (callback: () => void) => {
if (!Global.subscriptions[storeId]) {
Global.subscriptions[storeId] = []
Expand Down

0 comments on commit 19e9ea0

Please sign in to comment.