From 0293ee9c5a74e0e406b39d37b60828a39e3435e0 Mon Sep 17 00:00:00 2001 From: awmleer Date: Wed, 16 Mar 2022 11:19:15 +0800 Subject: [PATCH] enhance: (Picker & PickerView) add cache for `generateColumnsExtend` --- src/components/cascade-picker/demos/demo1.tsx | 4 +- src/components/picker-view/columns-extend.tsx | 43 +++++++++++-------- src/components/picker-view/picker-view.tsx | 4 +- src/components/picker/picker.tsx | 4 +- src/utils/with-cache.ts | 9 ++++ 5 files changed, 39 insertions(+), 25 deletions(-) create mode 100644 src/utils/with-cache.ts diff --git a/src/components/cascade-picker/demos/demo1.tsx b/src/components/cascade-picker/demos/demo1.tsx index c7fe324bad..b6d841e9bb 100644 --- a/src/components/cascade-picker/demos/demo1.tsx +++ b/src/components/cascade-picker/demos/demo1.tsx @@ -53,8 +53,8 @@ function CascadePickerDemo() { onClose={() => { setVisible(false) }} - onConfirm={val => { - console.log('onConfirm', val) + onConfirm={(val, extend) => { + console.log('onConfirm', val, extend.items) }} onSelect={val => { console.log('onSelect', val) diff --git a/src/components/picker-view/columns-extend.tsx b/src/components/picker-view/columns-extend.tsx index 25e00d0bd5..a3766a3ed3 100644 --- a/src/components/picker-view/columns-extend.tsx +++ b/src/components/picker-view/columns-extend.tsx @@ -4,39 +4,44 @@ import type { PickerValue, PickerValueExtend, } from './picker-view' +import { withCache } from '../../utils/with-cache' export function generateColumnsExtend( rawColumns: PickerViewProps['columns'], val: PickerValue[] ) { - // let columns: PickerColumn[] | null = null + const columns = withCache(() => { + const c = typeof rawColumns === 'function' ? rawColumns(val) : rawColumns + return c.map(column => + column.map(item => + typeof item === 'string' + ? { + label: item, + value: item, + } + : item + ) + ) + }) + const items = withCache(() => { + return val.map((v, index) => { + const column = columns()[index] + if (!column) return null + return column.find(item => item.value === v) ?? null + }) + }) const extend: PickerValueExtend = { get columns() { - const c = typeof rawColumns === 'function' ? rawColumns(val) : rawColumns - return c.map(column => - column.map(item => - typeof item === 'string' - ? { - label: item, - value: item, - } - : item - ) - ) + return columns() }, get items() { - console.log('items') - return val.map((v, index) => { - const column = extend.columns[index] - if (!column) return null - return column.find(item => item.value === v) ?? null - }) + return items() }, } return extend } -export function useColumnsAndExtend( +export function useColumnsExtend( rawColumns: PickerViewProps['columns'], value: PickerValue[] ) { diff --git a/src/components/picker-view/picker-view.tsx b/src/components/picker-view/picker-view.tsx index 91dfdc0702..f3d66edec0 100644 --- a/src/components/picker-view/picker-view.tsx +++ b/src/components/picker-view/picker-view.tsx @@ -1,7 +1,7 @@ import React, { memo, ReactNode, useCallback, useEffect, useState } from 'react' import { mergeProps } from '../../utils/with-default-props' import { Wheel } from './wheel' -import { useColumnsAndExtend } from './columns-extend' +import { useColumnsExtend } from './columns-extend' import { NativeProps, withNativeProps } from '../../utils/native-props' import { useDebounceEffect } from 'ahooks' @@ -58,7 +58,7 @@ export const PickerView = memo(p => { } }, [props.value, innerValue]) - const extend = useColumnsAndExtend(props.columns, innerValue) + const extend = useColumnsExtend(props.columns, innerValue) const columns = extend.columns useDebounceEffect( diff --git a/src/components/picker/picker.tsx b/src/components/picker/picker.tsx index 1ca33104b5..623afec6ed 100644 --- a/src/components/picker/picker.tsx +++ b/src/components/picker/picker.tsx @@ -12,7 +12,7 @@ import { import PickerView from '../picker-view' import { generateColumnsExtend, - useColumnsAndExtend, + useColumnsExtend, } from '../picker-view/columns-extend' import { useConfig } from '../config-provider' import { useMemoizedFn } from 'ahooks' @@ -69,7 +69,7 @@ export const Picker = memo(p => { }, }) - const extend = useColumnsAndExtend(props.columns, value) + const extend = useColumnsExtend(props.columns, value) const [innerValue, setInnerValue] = useState(value) useEffect(() => { diff --git a/src/utils/with-cache.ts b/src/utils/with-cache.ts new file mode 100644 index 0000000000..0baba6303a --- /dev/null +++ b/src/utils/with-cache.ts @@ -0,0 +1,9 @@ +export function withCache(generate: () => T) { + let cache: T | null = null + return () => { + if (cache === null) { + cache = generate() + } + return cache + } +}