🎈 perf(购物页面): 选择客户项和商品项的性能优化
This commit is contained in:
parent
a115787a02
commit
bd08ba8df2
@ -15,6 +15,7 @@ type params = {
|
|||||||
disable?: boolean, //是否禁用
|
disable?: boolean, //是否禁用
|
||||||
}
|
}
|
||||||
export default ({minNum = 0, maxNum = 10000, step=1, digits = 0, defaultNum = 0, onChange, onBlue, onClickBtn, unit = '', disable = false}: params) => {
|
export default ({minNum = 0, maxNum = 10000, step=1, digits = 0, defaultNum = 0, onChange, onBlue, onClickBtn, unit = '', disable = false}: params) => {
|
||||||
|
console.log('Rerender component: Counter');
|
||||||
const [value, setValue] = useState<any>({count:defaultNum})
|
const [value, setValue] = useState<any>({count:defaultNum})
|
||||||
|
|
||||||
const onPlus = (event) => {
|
const onPlus = (event) => {
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import { View, Text, Image } from '@tarojs/components'
|
import { View, Text, Image } from '@tarojs/components'
|
||||||
import MCheckbox from '@/components/checkbox'
|
import MCheckbox from '@/components/checkbox'
|
||||||
import Counter from '@/components/counter'
|
import Counter from '@/components/counter'
|
||||||
import { FC, memo, ReactNode, useCallback, useEffect, useState } from 'react'
|
import { FC, forwardRef, memo, ReactNode, useCallback, useEffect, useState } from 'react'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
import { debounce } from '@/common/util'
|
import { debounce } from '@/common/util'
|
||||||
import { formatImgUrl, formatPriceDiv } from '@/common/format'
|
import { formatImgUrl, formatPriceDiv } from '@/common/format'
|
||||||
import { EnumSaleMode } from '@/common/Enumerate'
|
import { EnumSaleMode } from '@/common/Enumerate'
|
||||||
import { useNeedMemoCallback } from '@/use/useCommon'
|
|
||||||
import { selectList } from '../../config'
|
import { selectList } from '../../config'
|
||||||
import { ShoppingDispatchType, useShoppingDispatch, useShoppingState } from '../../context'
|
import { Goods, ShoppingDispatchType, ShoppingStateContextValue, useShoppingDispatch, useShoppingState } from '../../context'
|
||||||
type PropsType = {
|
type PropsType = {
|
||||||
|
state?: Goods
|
||||||
purchaserId: number
|
purchaserId: number
|
||||||
itemData: Record<string, any> & object
|
itemData: Record<string, any> & object
|
||||||
orderType: EnumSaleMode
|
orderType: EnumSaleMode
|
||||||
@ -18,119 +18,109 @@ type PropsType = {
|
|||||||
|
|
||||||
// 注意:如果在表单控件内部使用 useWatch,由于是直接从Context中取值,memo也会直接失去作用。
|
// 注意:如果在表单控件内部使用 useWatch,由于是直接从Context中取值,memo也会直接失去作用。
|
||||||
|
|
||||||
const ColorKindItem: FC<PropsType> = memo(
|
let ColorKindItem: FC<PropsType> = props => {
|
||||||
props => {
|
console.log('Rerender component: ColorKindItem')
|
||||||
console.log('Rerender component: ColorKindItem')
|
const { state: goods, purchaserId, itemData, orderType = EnumSaleMode.Bulk } = props
|
||||||
const { purchaserId, itemData, orderType = EnumSaleMode.Bulk } = props
|
// const { colorStore } = useShoppingState()
|
||||||
const { colorStore } = useShoppingState()
|
const dispatch = useShoppingDispatch()
|
||||||
const dispatch = useShoppingDispatch()
|
// console.log('checked==>', checked)
|
||||||
// @ts-ignore
|
// const { checked } = colorStore[purchaserId]['goodsKind']![itemData.id] || { checked: false }
|
||||||
const { checked } = colorStore[purchaserId]['goodsKind']![itemData.id] || { checked: false }
|
|
||||||
|
|
||||||
//格式化金额
|
//格式化金额
|
||||||
const formatPrice = (price: number) => {
|
const formatPrice = (price: number) => {
|
||||||
return Number(formatPriceDiv(price))
|
return Number(formatPriceDiv(price))
|
||||||
|
}
|
||||||
|
|
||||||
|
//格式化数量
|
||||||
|
const formatCount = itemData => {
|
||||||
|
return itemData.sale_mode == EnumSaleMode.Bulk ? itemData.roll : itemData.length / 100
|
||||||
|
}
|
||||||
|
|
||||||
|
//格式化单位
|
||||||
|
const formatUnit = itemData => {
|
||||||
|
return itemData.sale_mode == EnumSaleMode.Bulk ? '条' : '米'
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSelect = () => {
|
||||||
|
// console.log('handleSelect')
|
||||||
|
dispatch({
|
||||||
|
type: ShoppingDispatchType.UPDATE_CHANGED_CHECKBOX,
|
||||||
|
data: {
|
||||||
|
purchaserId: purchaserId,
|
||||||
|
goodsKind: { [itemData.id]: { ...goods!, checked: true } },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const handleClose = () => {
|
||||||
|
dispatch({
|
||||||
|
type: ShoppingDispatchType.UPDATE_CHANGED_CHECKBOX,
|
||||||
|
data: {
|
||||||
|
purchaserId: purchaserId,
|
||||||
|
goodsKind: { [itemData.id]: { ...goods!, checked: false } },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getInputValue = debounce(async (num, itemData) => {
|
||||||
|
if (itemData.sale_mode === EnumSaleMode.Bulk) {
|
||||||
|
itemData.roll = num
|
||||||
|
} else {
|
||||||
|
itemData.length = num
|
||||||
}
|
}
|
||||||
|
}, 300)
|
||||||
|
|
||||||
//格式化数量
|
return (
|
||||||
const formatCount = itemData => {
|
<MCheckbox
|
||||||
return itemData.sale_mode == EnumSaleMode.Bulk ? itemData.roll : itemData.length / 100
|
status={goods?.checked}
|
||||||
}
|
onSelect={handleSelect}
|
||||||
|
onClose={handleClose}
|
||||||
//格式化单位
|
customClassName={classnames(styles.checkbox, goods?.checked ? styles.selected : '')}
|
||||||
const formatUnit = itemData => {
|
customTextClass={styles.colorKindItem}>
|
||||||
return itemData.sale_mode == EnumSaleMode.Bulk ? '条' : '米'
|
<View className={styles['colorKindItem__left']}>
|
||||||
}
|
<Image className={styles['colorKindItem__left--image']} mode='aspectFill' src={formatImgUrl(itemData.product_color_texture_url)}></Image>
|
||||||
|
</View>
|
||||||
const handleSelect = () => {
|
<View className={styles['colorKindItem__center']}>
|
||||||
// console.log('handleSelect')
|
<Text className={styles['colorKindItem__center--title']}>
|
||||||
dispatch({
|
{itemData.product_code}# {itemData.product_name}
|
||||||
type: ShoppingDispatchType.UPDATE_CHANGED_CHECKBOX,
|
</Text>
|
||||||
data: {
|
<View className={styles['colorKindItem__center--detail']}>
|
||||||
purchaserId: purchaserId,
|
<Text className={styles['colorKindItem__center--ID']}>{itemData.product_color_code}</Text>
|
||||||
goodsKind: { [itemData.id]: { ...colorStore[purchaserId].goodsKind?.[itemData.id]!, checked: true } },
|
<Text className={styles['colorKindItem__center--description']}>{itemData.product_color_name}</Text>
|
||||||
},
|
|
||||||
})
|
|
||||||
// setChangedCheckbox({
|
|
||||||
// purchaserId: purchaserId,
|
|
||||||
// goodsKind: { [itemData.id]: { ...colorStore[purchaserId].goodsKind?.[itemData.id]!, checked: true } },
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
const handleClose = () => {
|
|
||||||
dispatch({
|
|
||||||
type: ShoppingDispatchType.UPDATE_CHANGED_CHECKBOX,
|
|
||||||
data: {
|
|
||||||
purchaserId: purchaserId,
|
|
||||||
goodsKind: { [itemData.id]: { ...colorStore[purchaserId].goodsKind?.[itemData.id]!, checked: false } },
|
|
||||||
},
|
|
||||||
})
|
|
||||||
// setChangedCheckbox({
|
|
||||||
// purchaserId: purchaserId,
|
|
||||||
// goodsKind: { [itemData.id]: { ...colorStore[purchaserId].goodsKind?.[itemData.id]!, checked: false } },
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
|
|
||||||
const getInputValue = debounce(async (num, itemData) => {
|
|
||||||
if (itemData.sale_mode === EnumSaleMode.Bulk) {
|
|
||||||
itemData.roll = num
|
|
||||||
} else {
|
|
||||||
itemData.length = num
|
|
||||||
}
|
|
||||||
}, 300)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<MCheckbox
|
|
||||||
status={checked}
|
|
||||||
onSelect={handleSelect}
|
|
||||||
onClose={handleClose}
|
|
||||||
customClassName={classnames(styles.checkbox, checked ? styles.selected : '')}
|
|
||||||
customTextClass={styles.colorKindItem}>
|
|
||||||
<View className={styles['colorKindItem__left']}>
|
|
||||||
<Image className={styles['colorKindItem__left--image']} mode='aspectFill' src={formatImgUrl(itemData.product_color_texture_url)}></Image>
|
|
||||||
</View>
|
</View>
|
||||||
<View className={styles['colorKindItem__center']}>
|
</View>
|
||||||
<Text className={styles['colorKindItem__center--title']}>
|
<View className={styles['colorKindItem__right']}>
|
||||||
{itemData.product_code}# {itemData.product_name}
|
<View className={styles['colorKindItem__right--price']}>¥ {formatPrice(itemData.sale_price)}/kg</View>
|
||||||
</Text>
|
<View className={styles['colorKindItem__right--counter']}>
|
||||||
<View className={styles['colorKindItem__center--detail']}>
|
<Counter
|
||||||
<Text className={styles['colorKindItem__center--ID']}>{itemData.product_color_code}</Text>
|
onBlue={e => getInputValue(e, itemData)}
|
||||||
<Text className={styles['colorKindItem__center--description']}>{itemData.product_color_name}</Text>
|
defaultNum={formatCount(itemData)}
|
||||||
</View>
|
step={selectList[orderType].step}
|
||||||
|
digits={selectList[orderType].digits}
|
||||||
|
onClickBtn={e => getInputValue(e, itemData)}
|
||||||
|
unit={formatUnit(itemData)}
|
||||||
|
minNum={selectList[orderType].minNum}
|
||||||
|
maxNum={selectList[orderType].maxNum}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View className={styles['colorKindItem__right']}>
|
</View>
|
||||||
<View className={styles['colorKindItem__right--price']}>¥ {formatPrice(itemData.sale_price)}/kg</View>
|
</MCheckbox>
|
||||||
<View className={styles['colorKindItem__right--counter']}>
|
)
|
||||||
<Counter
|
}
|
||||||
onBlue={e => getInputValue(e, itemData)}
|
// State 分割组件 思路就是把 context直接通过props的形式传给组件,这样的话就解决了context强制刷新memo的问题了
|
||||||
defaultNum={formatCount(itemData)}
|
const withStateSlice = (comp, slice) => {
|
||||||
step={selectList[orderType].step}
|
const MemoComp = memo(comp)
|
||||||
digits={selectList[orderType].digits}
|
const Wrapper = (props, ref) => {
|
||||||
onClickBtn={e => getInputValue(e, itemData)}
|
const state = useShoppingState()
|
||||||
unit={formatUnit(itemData)}
|
return <MemoComp ref={ref} state={slice(state, props)} {...props} />
|
||||||
minNum={selectList[orderType].minNum}
|
}
|
||||||
maxNum={selectList[orderType].maxNum}
|
return memo(forwardRef(Wrapper))
|
||||||
/>
|
}
|
||||||
</View>
|
|
||||||
</View>
|
ColorKindItem = withStateSlice(
|
||||||
</MCheckbox>
|
ColorKindItem,
|
||||||
// <View>1111</View>
|
(state: ShoppingStateContextValue, props: PropsType) => {
|
||||||
)
|
return state.colorStore[props.purchaserId]['goodsKind']![props.itemData.id]
|
||||||
},
|
|
||||||
(preProp, nextProp) => {
|
|
||||||
const stringifyPreProp = JSON.stringify(preProp.itemData)
|
|
||||||
const stringifyNextProp = JSON.stringify(nextProp.itemData)
|
|
||||||
// console.log('memo==>', preProp, nextProp)
|
|
||||||
let needMemoized = true
|
|
||||||
if (preProp.purchaserId !== nextProp.purchaserId) {
|
|
||||||
needMemoized = false
|
|
||||||
}
|
|
||||||
if (preProp.orderType !== nextProp.orderType) {
|
|
||||||
needMemoized = false
|
|
||||||
}
|
|
||||||
if (stringifyPreProp !== stringifyNextProp) {
|
|
||||||
needMemoized = false
|
|
||||||
}
|
|
||||||
return needMemoized
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export default ColorKindItem
|
export default ColorKindItem
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Text, View } from '@tarojs/components'
|
import { Text, View } from '@tarojs/components'
|
||||||
import { FC, memo, useEffect, useMemo, useState, useTransition } from 'react'
|
import { FC, forwardRef, memo, useEffect, useMemo, useState, useTransition } from 'react'
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import { formatMeterDiv } from '@/common/format'
|
import { formatMeterDiv } from '@/common/format'
|
||||||
@ -9,14 +9,29 @@ import Divider from '@/components/divider'
|
|||||||
import ColorKindItem from '../colorKindItem'
|
import ColorKindItem from '../colorKindItem'
|
||||||
import { EnumSaleMode } from '@/common/Enumerate'
|
import { EnumSaleMode } from '@/common/Enumerate'
|
||||||
import { selectList } from '../../config'
|
import { selectList } from '../../config'
|
||||||
import { Goods, ShoppingDispatchType, useShoppingDispatch, useShoppingState } from '../../context'
|
import { Goods, ShoppingDispatchType, ShoppingStateContextValue, useShoppingDispatch, useShoppingState } from '../../context'
|
||||||
import IconFont from '@/components/iconfont/iconfont'
|
import IconFont from '@/components/iconfont/iconfont'
|
||||||
import { isEmptyObject } from '@/common/common'
|
import { isEmptyObject } from '@/common/common'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import LoadingCard from '@/components/loadingCard'
|
import LoadingCard from '@/components/loadingCard'
|
||||||
|
|
||||||
type PropsType = {
|
interface ButtonPropsType {
|
||||||
itemData?: ShoppingCartData
|
isActive: boolean
|
||||||
|
onClick?: Function
|
||||||
|
children?: React.ReactNode
|
||||||
|
customStyle?: React.CSSProperties
|
||||||
|
}
|
||||||
|
// 订单类型
|
||||||
|
const SaleModeButton: FC<ButtonPropsType> = props => {
|
||||||
|
const { onClick, children, isActive = false, customStyle } = props
|
||||||
|
const handleClick = () => {
|
||||||
|
onClick?.()
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<View className={classnames(styles.saleModeButton, isActive && styles['saleModeButton--active'])} style={customStyle} onClick={handleClick}>
|
||||||
|
<View className={classnames(styles['saleModeButton--text'])}>{children}</View>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const DrawerButton = memo<{ isOpen: boolean }>(({ isOpen }) => {
|
const DrawerButton = memo<{ isOpen: boolean }>(({ isOpen }) => {
|
||||||
@ -33,9 +48,17 @@ enum BackEndSaleModeListFieldMap {
|
|||||||
weight_cut_color_list = 2,
|
weight_cut_color_list = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default memo<PropsType>(props => {
|
type PropsType = {
|
||||||
const { itemData } = props
|
itemData?: ShoppingCartData
|
||||||
|
state?: {
|
||||||
|
goodsKind?: Goods
|
||||||
|
currentCheckedPurchaserId?: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let ShoppingCartItem: FC<PropsType> = props => {
|
||||||
|
const { itemData, state } = props
|
||||||
|
const { goodsKind, currentCheckedPurchaserId } = state!
|
||||||
const dispatch = useShoppingDispatch()
|
const dispatch = useShoppingDispatch()
|
||||||
|
|
||||||
const [openDetail, setOpenDetail] = useState(false)
|
const [openDetail, setOpenDetail] = useState(false)
|
||||||
@ -55,55 +78,25 @@ export default memo<PropsType>(props => {
|
|||||||
dispatch({ type: ShoppingDispatchType.UPDATE_SELECTED_AMOUNT, data: 0 })
|
dispatch({ type: ShoppingDispatchType.UPDATE_SELECTED_AMOUNT, data: 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
const { currentCheckedPurchaserId, colorStore } = useShoppingState()
|
// const { currentCheckedPurchaserId, colorStore } = useShoppingState()
|
||||||
|
|
||||||
console.log('Rerender component: shoppingCartItem')
|
console.log('Rerender component: shoppingCartItem')
|
||||||
|
|
||||||
// const memoList = useMemo(() => {
|
|
||||||
// console.log('ext useMemo')
|
|
||||||
// const component = itemData?.[BackEndSaleModeListFieldMap[selected]].map(item => {
|
|
||||||
// dispatch({
|
|
||||||
// type: ShoppingDispatchType.UPDATE_CHANGED_CHECKBOX,
|
|
||||||
// data: {
|
|
||||||
// purchaserId: itemData?.purchaser_id!,
|
|
||||||
// goodsKind: {
|
|
||||||
// [item?.id]: {
|
|
||||||
// id: item?.id,
|
|
||||||
// estimate_amount: item.estimate_amount,
|
|
||||||
// checked: false,
|
|
||||||
// product_code: item.product_code,
|
|
||||||
// product_color_code: item.product_color_code,
|
|
||||||
// sale_mode: item.sale_mode,
|
|
||||||
// count: selected === EnumSaleMode.Bulk ? item.roll : Number(formatMeterDiv(item.length)),
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
// return <ColorKindItem purchaserId={itemData.purchaser_id} key={item.id} itemData={item} orderType={selected}></ColorKindItem>
|
|
||||||
// })
|
|
||||||
// // 向 context 中初始化数据
|
|
||||||
// const result = itemData?.[BackEndSaleModeListFieldMap[selected]].length !== 0 ? component : <View className={styles.noList}>暂无数据</View>
|
|
||||||
|
|
||||||
// return result
|
|
||||||
// }, [itemData, selected])
|
|
||||||
|
|
||||||
const handleClickLayout = () => {
|
const handleClickLayout = () => {
|
||||||
if (currentCheckedPurchaserId === itemData?.purchaser_id) {
|
if (currentCheckedPurchaserId === itemData?.purchaser_id) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dispatch({ type: ShoppingDispatchType.UPDATE_SELECTED_AMOUNT, data: 0 })
|
dispatch({ type: ShoppingDispatchType.UPDATE_SELECTED_AMOUNT, data: 0 })
|
||||||
// setSelectedAmount(0)
|
|
||||||
// setCurrentCheckedSaleMode(selected)
|
|
||||||
dispatch({ type: ShoppingDispatchType.UPDATE_CURRENT_CHECKED_SALEMODE, data: selected })
|
dispatch({ type: ShoppingDispatchType.UPDATE_CURRENT_CHECKED_SALEMODE, data: selected })
|
||||||
dispatch({ type: ShoppingDispatchType.UPDATE_CURRENT_CHECKED_PURCHASERID, data: itemData?.purchaser_id as number })
|
dispatch({ type: ShoppingDispatchType.UPDATE_CURRENT_CHECKED_PURCHASERID, data: itemData?.purchaser_id as number })
|
||||||
// setCurrentCheckedPurchaserId(itemData?.purchaser_id as number)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 统计已选面料
|
// 统计已选面料
|
||||||
const materialChecked = useMemo(() => {
|
const materialChecked = useMemo(() => {
|
||||||
const targetGoodsKind = colorStore?.[itemData?.purchaser_id!]?.['goodsKind']
|
const targetGoodsKind = goodsKind
|
||||||
if (!targetGoodsKind || isEmptyObject(targetGoodsKind)) return 0
|
if (!targetGoodsKind || isEmptyObject(targetGoodsKind)) return 0
|
||||||
return new Set(
|
return new Set(
|
||||||
|
// @ts-ignore
|
||||||
Object.values(targetGoodsKind)?.reduce((prev, item: Goods) => {
|
Object.values(targetGoodsKind)?.reduce((prev, item: Goods) => {
|
||||||
if (item.checked && item.sale_mode === selected) {
|
if (item.checked && item.sale_mode === selected) {
|
||||||
return [...prev, item.product_code]
|
return [...prev, item.product_code]
|
||||||
@ -111,13 +104,14 @@ export default memo<PropsType>(props => {
|
|||||||
return prev
|
return prev
|
||||||
}, []),
|
}, []),
|
||||||
).size
|
).size
|
||||||
}, [colorStore, currentCheckedPurchaserId, selected, itemData])
|
}, [goodsKind, currentCheckedPurchaserId, selected, itemData])
|
||||||
|
|
||||||
// 统计已选颜色
|
// 统计已选颜色
|
||||||
const colorChecked = useMemo(() => {
|
const colorChecked = useMemo(() => {
|
||||||
const targetGoodsKind = colorStore?.[itemData?.purchaser_id!]?.['goodsKind']
|
const targetGoodsKind = goodsKind
|
||||||
if (!targetGoodsKind || isEmptyObject(targetGoodsKind)) return 0
|
if (!targetGoodsKind || isEmptyObject(targetGoodsKind)) return 0
|
||||||
return new Set(
|
return new Set(
|
||||||
|
// @ts-ignore
|
||||||
Object.values(targetGoodsKind).reduce((prev, item: Goods) => {
|
Object.values(targetGoodsKind).reduce((prev, item: Goods) => {
|
||||||
if (item.checked && item.sale_mode === selected) {
|
if (item.checked && item.sale_mode === selected) {
|
||||||
return [...prev, item.product_color_code]
|
return [...prev, item.product_color_code]
|
||||||
@ -125,21 +119,23 @@ export default memo<PropsType>(props => {
|
|||||||
return prev
|
return prev
|
||||||
}, []),
|
}, []),
|
||||||
).size
|
).size
|
||||||
}, [colorStore, currentCheckedPurchaserId, selected, itemData])
|
}, [goodsKind, currentCheckedPurchaserId, selected, itemData])
|
||||||
|
|
||||||
// 统计已选条数 / 米数
|
// 统计已选条数 / 米数
|
||||||
const lengthOrRollChecked = useMemo(() => {
|
const lengthOrRollChecked = useMemo(() => {
|
||||||
const targetGoodsKind = colorStore?.[itemData?.purchaser_id!]?.['goodsKind']
|
const targetGoodsKind = goodsKind
|
||||||
if (!targetGoodsKind || isEmptyObject(targetGoodsKind)) return 0
|
if (!targetGoodsKind || isEmptyObject(targetGoodsKind)) return 0
|
||||||
return (
|
return (
|
||||||
|
// @ts-ignore
|
||||||
Object.values(targetGoodsKind).reduce((prev, item: Goods) => {
|
Object.values(targetGoodsKind).reduce((prev, item: Goods) => {
|
||||||
if (item.checked && item.sale_mode === selected) {
|
if (item.checked && item.sale_mode === selected) {
|
||||||
|
// @ts-ignore
|
||||||
return prev + item.count
|
return prev + item.count
|
||||||
}
|
}
|
||||||
return prev
|
return prev
|
||||||
}, 0) || 0
|
}, 0) || 0
|
||||||
)
|
)
|
||||||
}, [colorStore, currentCheckedPurchaserId, selected, itemData])
|
}, [goodsKind, currentCheckedPurchaserId, selected, itemData])
|
||||||
|
|
||||||
const [isPending, startTransition] = useTransition()
|
const [isPending, startTransition] = useTransition()
|
||||||
|
|
||||||
@ -205,7 +201,6 @@ export default memo<PropsType>(props => {
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className={styles.orderContainer}>
|
<View className={styles.orderContainer}>
|
||||||
{/* <GoodsList itemData={itemData} selected={selected} /> */}
|
|
||||||
<GoodsList itemData={itemData} selected={selected} isPending={isPending} startTransition={startTransition} />
|
<GoodsList itemData={itemData} selected={selected} isPending={isPending} startTransition={startTransition} />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
@ -213,7 +208,7 @@ export default memo<PropsType>(props => {
|
|||||||
)}
|
)}
|
||||||
</LayoutBlock>
|
</LayoutBlock>
|
||||||
)
|
)
|
||||||
})
|
}
|
||||||
|
|
||||||
interface GoodsListPropType {
|
interface GoodsListPropType {
|
||||||
itemData?: ShoppingCartData
|
itemData?: ShoppingCartData
|
||||||
@ -271,22 +266,29 @@ const GoodsList = memo<GoodsListPropType>(props => {
|
|||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
// State 分割组件 思路就是把 context直接通过props的形式传给组件,这样的话就解决了context强制刷新memo的问题了
|
||||||
interface ButtonPropsType {
|
const withStateSlice = (comp, slice) => {
|
||||||
isActive: boolean
|
const MemoComp = memo(comp, (prevProps, nextProps)=>{
|
||||||
onClick?: Function
|
let needMemo = true
|
||||||
children?: React.ReactNode
|
if (JSON.stringify(prevProps.itemData) !== JSON.stringify(nextProps.itemData)) {
|
||||||
customStyle?: React.CSSProperties
|
needMemo = false
|
||||||
}
|
}
|
||||||
// 订单类型
|
if(JSON.stringify(prevProps.state) !== JSON.stringify(nextProps.state)){
|
||||||
const SaleModeButton: FC<ButtonPropsType> = props => {
|
needMemo = false
|
||||||
const { onClick, children, isActive = false, customStyle } = props
|
}
|
||||||
const handleClick = () => {
|
return needMemo
|
||||||
onClick?.()
|
})
|
||||||
|
const Wrapper = (props, ref) => {
|
||||||
|
const state = useShoppingState()
|
||||||
|
console.log('state===>', state)
|
||||||
|
return <MemoComp ref={ref} state={slice(state, props)} {...props} />
|
||||||
}
|
}
|
||||||
return (
|
return memo(forwardRef(Wrapper))
|
||||||
<View className={classnames(styles.saleModeButton, isActive && styles['saleModeButton--active'])} style={customStyle} onClick={handleClick}>
|
|
||||||
<View className={classnames(styles['saleModeButton--text'])}>{children}</View>
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShoppingCartItem = withStateSlice(ShoppingCartItem, (state: ShoppingStateContextValue, props) => ({
|
||||||
|
goodsKind: state.colorStore?.[props.itemData?.purchaser_id]?.['goodsKind']!,
|
||||||
|
currentCheckedPurchaserId: state.currentCheckedPurchaserId,
|
||||||
|
}))
|
||||||
|
|
||||||
|
export default ShoppingCartItem
|
||||||
|
Loading…
x
Reference in New Issue
Block a user