generated from arvinxx/monorepo-template
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
♻️ refactor: 基于 StoreUpdater 重构受控模式代码
- Loading branch information
Showing
10 changed files
with
215 additions
and
139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
/* istanbul ignore file */ | ||
import type { FC } from 'react'; | ||
import React from 'react'; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
137 changes: 137 additions & 0 deletions
137
packages/sortable-list/src/hooks/useStoreUpdater.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
import React, { useCallback, useState } from 'react'; | ||
import { act, renderHook } from '@testing-library/react-hooks'; | ||
|
||
import { useStoreUpdater } from './useStoreUpdater'; | ||
import type { SortableItemList } from '../types'; | ||
import { createStore, Provider, useStore } from '../store'; | ||
|
||
const renderOptions = { | ||
wrapper: ({ children }) => ( | ||
<Provider createStore={createStore}>{children}</Provider> | ||
), | ||
}; | ||
describe('useStoreUpdater', () => { | ||
it('外部控制初始值', () => { | ||
const { result } = renderHook(() => { | ||
useStoreUpdater({ defaultData: [{ id: '123' }] }); | ||
|
||
return useStore((s) => s.data); | ||
}, renderOptions); | ||
expect(result.current).toEqual([{ id: '123' }]); | ||
}); | ||
|
||
it('外部设置值', () => { | ||
const { result } = renderHook(() => { | ||
useStoreUpdater({ data: [{ id: '123' }] }); | ||
return useStore((s) => s.data); | ||
}, renderOptions); | ||
|
||
expect(result.current).toEqual([{ id: '123' }]); | ||
}); | ||
|
||
it('外部 setValue', () => { | ||
const controlledValue: SortableItemList = [ | ||
{ id: '1' }, | ||
{ id: '2' }, | ||
{ id: '3' }, | ||
]; | ||
|
||
const { result } = renderHook(() => { | ||
const [value, setConfig] = useState<SortableItemList>(); | ||
useStoreUpdater({ | ||
data: value, | ||
}); | ||
|
||
const data = useStore((s) => s.data); | ||
return { data, setConfig }; | ||
}, renderOptions); | ||
|
||
act(() => { | ||
result.current.setConfig(controlledValue); | ||
}); | ||
|
||
expect(result.current.data).toEqual([ | ||
{ id: '1' }, | ||
{ id: '2' }, | ||
{ id: '3' }, | ||
]); | ||
}); | ||
|
||
it('没有 onChange 时不更改', () => { | ||
const useNoOnChange = () => { | ||
const [data] = useState([{ id: '1' }]); | ||
useStoreUpdater({ data: data }); | ||
|
||
const store = useStore(); | ||
return { store, data }; | ||
}; | ||
const { result } = renderHook(() => useNoOnChange(), renderOptions); | ||
// | ||
// | ||
act(() => { | ||
result.current.store.addItem({ id: '333' }); | ||
}); | ||
|
||
expect(result.current.data).toEqual([{ id: '1' }]); | ||
}); | ||
|
||
it('内部修改值 外部 value 更新', () => { | ||
const { result } = renderHook(() => { | ||
const [value, setConfig] = useState<SortableItemList>([ | ||
{ id: '1' }, | ||
{ id: '2' }, | ||
{ id: '3' }, | ||
]); | ||
|
||
const func = useCallback((data) => { | ||
console.log('xuga', data); | ||
setConfig(data); | ||
}, []); | ||
|
||
useStoreUpdater({ | ||
data: value, | ||
onDataChange: func, | ||
}); | ||
|
||
const reorder = useStore((s) => s.reorder); | ||
|
||
return { value, reorder }; | ||
}, renderOptions); | ||
|
||
expect(result.current.value).toEqual([ | ||
{ id: '1' }, | ||
{ id: '2' }, | ||
{ id: '3' }, | ||
]); | ||
|
||
act(() => { | ||
result.current.reorder(2, 0); | ||
}); | ||
|
||
expect(result.current.value).toEqual([ | ||
{ id: '3' }, | ||
{ id: '1' }, | ||
{ id: '2' }, | ||
]); | ||
|
||
act(() => { | ||
result.current.reorder(1, 0); | ||
}); | ||
|
||
expect(result.current.value).toEqual([ | ||
{ id: '1' }, | ||
{ id: '3' }, | ||
{ id: '2' }, | ||
]); | ||
|
||
act(() => { | ||
result.current.reorder(1, 1); | ||
}); | ||
|
||
expect(result.current.value).toEqual([ | ||
{ id: '1' }, | ||
{ id: '3' }, | ||
{ id: '2' }, | ||
]); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { useEffect } from 'react'; | ||
import type { StoreUpdaterProps } from '../types'; | ||
import { useStore } from '../store'; | ||
import shallow from 'zustand/shallow'; | ||
|
||
export const useStoreUpdater = ({ | ||
data, | ||
defaultData, | ||
onDataChange, | ||
}: StoreUpdaterProps) => { | ||
const { syncOnDataChange, syncOutsideData } = useStore( | ||
(s) => ({ | ||
syncOutsideData: s.syncOutsideData, | ||
syncOnDataChange: s.syncOnDataChange, | ||
}), | ||
shallow, | ||
); | ||
|
||
useEffect(() => { | ||
if (defaultData) { | ||
syncOutsideData(defaultData); | ||
} | ||
}, []); | ||
|
||
useEffect(() => { | ||
if (!data) return; | ||
syncOutsideData(data); | ||
}, [data]); | ||
|
||
useEffect(() => { | ||
if (!onDataChange) return; | ||
|
||
syncOnDataChange(onDataChange); | ||
}, [onDataChange]); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.