Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(CheckSelect): 修复异步加载数据选中项未缓存问题 #2234

Merged
merged 1 commit into from
Sep 14, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions packages/ui/check-select/src/use-check-select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { uniqBy } from '@hi-ui/array-utils'
import { useCheck as useCheckDefault } from '@hi-ui/use-check'
import { CheckSelectDataItem, CheckSelectItemEventData, CheckSelectMergedItem } from './types'
import { useLatestCallback, useLatestRef } from '@hi-ui/use-latest'
import { useCache } from '@hi-ui/use-cache'
import { useFlattenData, useData } from './hooks'

const NOOP_ARRAY = [] as []
Expand All @@ -21,7 +22,8 @@ export const useCheckSelect = ({
...rest
}: UseCheckSelectProps) => {
const data = useData({ data: dataProp, children })
const flattedData = useFlattenData({ data, fieldNames })
const [cacheData, setCacheData] = useCache<any[]>(data)
const flattedData = useFlattenData({ data: cacheData, fieldNames })
const flattedDataRef = useLatestRef(flattedData)

const [value, tryChangeValue] = useUncontrolledState(defaultValue, valueProp, onChangeProp)
Expand All @@ -32,6 +34,25 @@ export const useCheckSelect = ({
// 扁平化的选中数据,可能包括异步临时选中缓存数据
const [checkedItems, setCheckedItems] = useState<CheckSelectItemEventData[]>([])

/**
* 更新缓存的 data 数据
* 兼容在搜索异步加载结果的场景时,将选中的项加入到 cacheData 数据中,这样再次打开下拉框时可以显示之前选中的值
*/
const updateCacheData = useCallback(
(nextCheckedItems: any[]) => {
const newData = [...cacheData]

nextCheckedItems.forEach((item) => {
if (!flattedData.find((dataItem) => dataItem.id === item.id)) {
newData.push('raw' in item ? item.raw : item)
}
})

setCacheData(newData)
},
[cacheData, flattedData, setCacheData]
)

const proxyTryChangeValue = useCallback(
(
value: React.ReactText[],
Expand Down Expand Up @@ -63,8 +84,11 @@ export const useCheckSelect = ({
changedItems.map((item) => ('raw' in item ? item.raw : item)),
nextCheckedItems.map((item) => ('raw' in item ? item.raw : item))
)

// 每次更新 value 时,同步更新下 cacheData
updateCacheData(nextCheckedItems)
},
[tryChangeValue, onSelectLatest, flattedDataRef, usedItemsRef]
[flattedDataRef, tryChangeValue, updateCacheData, onSelectLatest]
)

const [onOptionCheck, isCheckedId] = useCheckDefault({
Expand Down