🐞 fix(购物页面): 修复多选流程产生的bug
This commit is contained in:
@@ -1,33 +1,40 @@
|
||||
import { formatPriceDiv } from '@/common/format'
|
||||
import NormalButton from '@/components/normalButton'
|
||||
import { View, Text } from '@tarojs/components'
|
||||
import { memo, useState } from 'react'
|
||||
import { memo, SetStateAction, useMemo, useRef, useState } from 'react'
|
||||
import styles from './index.module.scss'
|
||||
import MCheckbox from '@/components/checkbox'
|
||||
import { usePropsValue } from '@/use/useCommon'
|
||||
import { ShoppingDispatchType, useShoppingDispatch } from '../../context'
|
||||
|
||||
type PropsType = {
|
||||
onDelete?: Function
|
||||
onSelectCheckbox?: (bool: boolean) => void
|
||||
disabled?: boolean
|
||||
isSelectAll?: boolean
|
||||
}
|
||||
|
||||
export default memo<PropsType>(props => {
|
||||
const { onDelete, onSelectCheckbox, disabled = false } = props
|
||||
|
||||
export default (props: PropsType) => {
|
||||
const { onDelete, onSelectCheckbox, disabled = false, isSelectAll: selectAll = false } = props
|
||||
const dispatch = useShoppingDispatch()
|
||||
console.log('isSelectAll==>', selectAll)
|
||||
const handleDelete = () => {
|
||||
onDelete && onDelete()
|
||||
}
|
||||
|
||||
const selectCallBack = () => {
|
||||
onSelectCheckbox && onSelectCheckbox(true)
|
||||
setSelectAll(true)
|
||||
dispatch({ type: ShoppingDispatchType.UPDATE_MULTIPLE_SELECTION, data: true })
|
||||
}
|
||||
const closeCallBack = () => {
|
||||
setSelectAll(false)
|
||||
dispatch({ type: ShoppingDispatchType.UPDATE_MULTIPLE_SELECTION, data: false })
|
||||
onSelectCheckbox && onSelectCheckbox(false)
|
||||
}
|
||||
|
||||
const [isSelectAll, setSelectAll] = useState(false)
|
||||
const [isSelectAll, setSelectAll] = usePropsValue({
|
||||
value: selectAll,
|
||||
defaultValue: false,
|
||||
})
|
||||
|
||||
return (
|
||||
<View className={styles.bottomBar}>
|
||||
@@ -50,4 +57,4 @@ export default memo<PropsType>(props => {
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -17,8 +17,6 @@ type PropsType = {
|
||||
orderType: EnumSaleMode
|
||||
}
|
||||
|
||||
// 注意:如果在表单控件内部使用 useWatch,由于是直接从Context中取值,memo也会直接失去作用。
|
||||
|
||||
let ColorKindItem: FC<PropsType> = props => {
|
||||
console.log('Rerender component: ColorKindItem')
|
||||
const { state: multipleSelection, purchaserId, itemData, orderType = EnumSaleMode.Bulk } = props
|
||||
@@ -111,7 +109,8 @@ let ColorKindItem: FC<PropsType> = props => {
|
||||
</MCheckbox>
|
||||
)
|
||||
}
|
||||
// State 分割组件 思路就是把 context直接通过props的形式传给组件,这样的话就解决了context强制刷新memo的问题了
|
||||
// State 分割组件 思路就是把 context 直接通过 props 的形式传给组件,这样的话就解决了 context 强制刷新 memo 的问题了
|
||||
// 那么当 context 内的 value 被更新的时候,react 只会强制渲染 Wrapper
|
||||
const withStateSlice = (comp, slice) => {
|
||||
const MemoComp = memo(comp)
|
||||
const Wrapper = (props, ref) => {
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import { Dispatch, FC, ReactNode, useEffect, useMemo, useReducer, useRef, useState } from 'react'
|
||||
import { ShoppingAction, ShoppingCartAction, ShoppingDispatchContext, ShoppingDispatchContextValue, ShoppingDispatchType, shoppingReducer, ShoppingStateContext } from '../../context'
|
||||
import { GoodsMeta, ColorStore, ShoppingStateContextValue } from '../../context'
|
||||
import { FC, ReactNode, useEffect, useReducer, useRef } from 'react'
|
||||
import {
|
||||
ShoppingAction,
|
||||
ShoppingDispatchContext,
|
||||
ShoppingDispatchContextValue,
|
||||
ShoppingDispatchType,
|
||||
shoppingReducer,
|
||||
ShoppingStateContext,
|
||||
} from '../../context'
|
||||
import { ColorStore, ShoppingStateContextValue } from '../../context'
|
||||
|
||||
export type TriggerCheckboxOptions = {
|
||||
colorStore: ColorStore
|
||||
@@ -13,6 +20,7 @@ type InitialState = {
|
||||
currentCheckedPurchaserId: number
|
||||
currentCheckedSaleMode: number
|
||||
isManageStatus: boolean
|
||||
isMultipleSelection: boolean
|
||||
selectedAmount: number
|
||||
}
|
||||
|
||||
@@ -33,17 +41,16 @@ export const ShoppingProvider: FC<ShoppingCartPropsType> = props => {
|
||||
currentCheckedPurchaserId: -1,
|
||||
currentCheckedSaleMode: 0,
|
||||
isManageStatus: false,
|
||||
isMultipleSelection: false,
|
||||
selectedAmount: 0,
|
||||
})
|
||||
|
||||
|
||||
|
||||
// 这里要在 useEffect 也就是刷新 state 后再调用,否则如果在 onFieldsChangeRef 修改值会覆盖掉上次修改
|
||||
useEffect(() => {
|
||||
onTriggerCheckboxRef.current?.({
|
||||
colorStore: state.colorStore,
|
||||
currentCheckedPurchaserId: state.currentCheckedPurchaserId,
|
||||
setSelectedAmount: (amount) => dispatch({ type: ShoppingDispatchType.UPDATE_SELECTED_AMOUNT,data: amount }),
|
||||
setSelectedAmount: amount => dispatch({ type: ShoppingDispatchType.UPDATE_SELECTED_AMOUNT, data: amount }),
|
||||
})
|
||||
}, [state.colorStore, state.currentCheckedPurchaserId])
|
||||
|
||||
|
||||
@@ -76,10 +76,9 @@ let ShoppingCartItem: FC<PropsType> = props => {
|
||||
dispatch({ type: ShoppingDispatchType.UPDATE_CURRENT_CHECKED_SALEMODE, data: type })
|
||||
// 重置预估金额
|
||||
dispatch({ type: ShoppingDispatchType.UPDATE_SELECTED_AMOUNT, data: 0 })
|
||||
dispatch({ type: ShoppingDispatchType.UPDATE_MULTIPLE_SELECTION, data: false })
|
||||
}
|
||||
|
||||
// const { currentCheckedPurchaserId, colorStore } = useShoppingState()
|
||||
|
||||
console.log('Rerender component: shoppingCartItem')
|
||||
|
||||
const handleClickLayout = () => {
|
||||
@@ -89,6 +88,7 @@ let ShoppingCartItem: FC<PropsType> = props => {
|
||||
dispatch({ type: ShoppingDispatchType.UPDATE_SELECTED_AMOUNT, data: 0 })
|
||||
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_MULTIPLE_SELECTION, data: false })
|
||||
}
|
||||
|
||||
// 统计已选面料
|
||||
@@ -259,7 +259,8 @@ const GoodsList = memo<GoodsListPropType>(props => {
|
||||
</>
|
||||
)
|
||||
})
|
||||
// State 分割组件 思路就是把 context直接通过props的形式传给组件,这样的话就解决了context强制刷新memo的问题了
|
||||
// State 分割组件 思路就是把 context 直接通过 props 的形式传给组件,这样的话就解决了 context 强制刷新 memo 的问题了
|
||||
// 那么当 context 内的 value 被更新的时候,react 只会强制渲染 Wrapper
|
||||
const withStateSlice = (comp, slice) => {
|
||||
const MemoComp = memo(comp, (prevProps, nextProps)=>{
|
||||
let needMemo = true
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { Dispatch, useRef } from 'react'
|
||||
import { EnumSaleMode } from '@/common/Enumerate'
|
||||
import React, { Dispatch } from 'react'
|
||||
import { useContext } from 'react'
|
||||
|
||||
/**
|
||||
@@ -31,7 +32,7 @@ export type Goods = {
|
||||
product_color_code: number // 颜色编号
|
||||
estimate_amount: number // 预估金额
|
||||
count: number // 已选的条数或米数
|
||||
sale_mode: number
|
||||
sale_mode: EnumSaleMode
|
||||
}
|
||||
// 分组
|
||||
export interface GoodsMeta {
|
||||
@@ -45,29 +46,32 @@ export interface GoodsMeta {
|
||||
}
|
||||
|
||||
export interface ShoppingStateContextValue {
|
||||
isManageStatus: boolean
|
||||
isManageStatus: boolean // 管理按钮的状态
|
||||
isMultipleSelection: boolean // 全选按钮的状态
|
||||
currentCheckedPurchaserId: number // 当前高亮的客户ID
|
||||
currentCheckedSaleMode: number
|
||||
currentCheckedSaleMode: EnumSaleMode
|
||||
colorStore: ColorStore
|
||||
selectedAmount: number
|
||||
}
|
||||
|
||||
export enum ShoppingDispatchType {
|
||||
UPDATE_MANAGE_STATUS = 'UPDATE_MANAGE_STATUS',
|
||||
UPDATE_MULTIPLE_SELECTION = 'UPDATE_MULTIPLE_SELECTION',
|
||||
UPDATE_CURRENT_CHECKED_PURCHASERID = 'UPDATE_CURRENT_CHECKED_PURCHASERID',
|
||||
UPDATE_CURRENT_CHECKED_SALEMODE = 'UPDATE_CURRENT_CHECKED_SALEMODE',
|
||||
UPDATE_COLOR_STORE = 'UPDATE_COLOR_STORE',
|
||||
UPDATE_SELECTED_AMOUNT = 'UPDATE_SELECTED_AMOUNT',
|
||||
UPDATE_CHANGED_CHECKBOX = 'UPDATE_CHANGED_CHECKBOX',
|
||||
}
|
||||
|
||||
// UPDATE_MultipleSelection
|
||||
export interface ShoppingDispatchContextValue {
|
||||
[ShoppingDispatchType.UPDATE_MANAGE_STATUS]: (isManageStatus: boolean) => void
|
||||
[ShoppingDispatchType.UPDATE_CURRENT_CHECKED_PURCHASERID]: (purchaserId: number) => void
|
||||
[ShoppingDispatchType.UPDATE_CURRENT_CHECKED_SALEMODE]: (saleMode: number) => void
|
||||
[ShoppingDispatchType.UPDATE_MANAGE_STATUS]: (isManageStatus: ShoppingStateContextValue['isManageStatus']) => void
|
||||
[ShoppingDispatchType.UPDATE_MULTIPLE_SELECTION]: (isMultipleSelection: ShoppingStateContextValue['isMultipleSelection']) => void
|
||||
[ShoppingDispatchType.UPDATE_CURRENT_CHECKED_PURCHASERID]: (purchaserId: ShoppingStateContextValue['currentCheckedPurchaserId']) => void
|
||||
[ShoppingDispatchType.UPDATE_CURRENT_CHECKED_SALEMODE]: (saleMode: ShoppingStateContextValue['currentCheckedSaleMode']) => void
|
||||
[ShoppingDispatchType.UPDATE_COLOR_STORE]: (colorStore: React.SetStateAction<ColorStore>) => void
|
||||
[ShoppingDispatchType.UPDATE_SELECTED_AMOUNT]: (amount: React.SetStateAction<number>) => void
|
||||
[ShoppingDispatchType.UPDATE_CHANGED_CHECKBOX]: (amount: React.SetStateAction<number>) => void
|
||||
[ShoppingDispatchType.UPDATE_SELECTED_AMOUNT]: (amount: React.SetStateAction<ShoppingStateContextValue['selectedAmount']>) => void
|
||||
[ShoppingDispatchType.UPDATE_CHANGED_CHECKBOX]: (amount: React.SetStateAction<ShoppingStateContextValue['selectedAmount']>) => void
|
||||
}
|
||||
|
||||
|
||||
@@ -82,6 +86,9 @@ export function shoppingReducer(state: ShoppingStateContextValue, action: Shoppi
|
||||
case ShoppingDispatchType.UPDATE_MANAGE_STATUS: {
|
||||
return { ...state, isManageStatus: data }
|
||||
}
|
||||
case ShoppingDispatchType.UPDATE_MULTIPLE_SELECTION: {
|
||||
return { ...state, isMultipleSelection: data }
|
||||
}
|
||||
case ShoppingDispatchType.UPDATE_CURRENT_CHECKED_PURCHASERID: {
|
||||
return { ...state, currentCheckedPurchaserId: data }
|
||||
}
|
||||
|
||||
@@ -46,12 +46,15 @@ interface InternalContainer {}
|
||||
const ShoppingCartContainer: FC<InternalContainer> = () => {
|
||||
let isFirst = useRef(true)
|
||||
|
||||
const { isManageStatus, selectedAmount, currentCheckedPurchaserId, currentCheckedSaleMode, colorStore } = useShoppingState()
|
||||
const { isMultipleSelection, isManageStatus, selectedAmount, currentCheckedPurchaserId, currentCheckedSaleMode, colorStore } = useShoppingState()
|
||||
|
||||
const dispatch = useShoppingDispatch()
|
||||
|
||||
// 管理
|
||||
const onStartToManage = () => {
|
||||
if(isManageStatus){
|
||||
handleSelectAllCheckbox(false) // 取消全选
|
||||
}
|
||||
dispatch({ type: ShoppingDispatchType.UPDATE_MANAGE_STATUS, data: !isManageStatus })
|
||||
}
|
||||
|
||||
@@ -230,6 +233,7 @@ const ShoppingCartContainer: FC<InternalContainer> = () => {
|
||||
{isManageStatus ? (
|
||||
<BottomEditBar
|
||||
disabled={currentCheckedPurchaserId < 0}
|
||||
isSelectAll={isMultipleSelection}
|
||||
onDelete={handleDelete}
|
||||
onSelectCheckbox={isAll => handleSelectAllCheckbox(isAll)}></BottomEditBar>
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user