巧用reduce 实现 checkbox 选中勾选联动
作者:互联网
在使用checkbox组件时经常遇到需要关联checkbox选中状态的需求
例如 A B C 三个checkbox 中,需要选中c时自动勾选上 A B,而取消A时需要取消B C的选中状态
思路:
- 添加时,每一项新建一个数组,通过reduce从前到后遍历每一个checkbox的value,数组中添加上上一子项的id
- 取消时,每一项新建一个数组,通过reduceRight从后到前遍历每一个checkbox的value,数组中添加上下一父项的id
- 通过两个数组配合checkbox的checked和onChange 即可以实现改效果
在真实的场景下返回的数据如下
const mock = [
{
canBeSettled: 'yes',
date: '2020-03-01',
id: 18,
settled: 'yes',
shareAmount: '17289.38',
tips: '200000.00 x 40% x (153/273) ',
},
{
canBeSettled: 'yes',
date: '2020-08-01',
id: 19,
settled: 'yes',
shareAmount: '17289.38',
tips: '200000.00 x 40% x (153/273) ',
},
{
canBeSettled: 'yes',
date: '2021-03-01',
id: 20,
settled: 'no',
shareAmount: '17289.38',
tips: '200000.00 x 40% x (153/273) ',
},
{
canBeSettled: 'yes',
date: '2021-08-01',
id: 21,
settled: 'no',
shareAmount: '17289.38',
tips: '200000.00 x 40% x (153/273) ',
},
{
canBeSettled: 'yes',
date: '2022-03-01',
id: 22,
settled: 'no',
shareAmount: '17289.38',
tips: '200000.00 x 40% x (153/273) ',
},
{
canBeSettled: 'yes',
date: '2022-08-01',
id: 23,
settled: 'no',
shareAmount: '44835.16',
tips: '200000.00 x 40% x (153/273) ',
},
{
canBeSettled: 'no',
date: '2023-03-01',
id: 24,
settled: 'no',
shareAmount: '17875.46',
tips: '200000.00 x 40% x (153/273) ',
},
]
这时可以用reduce来遍历格式化数据
const mockFilter = mock
.reduce((t, v, i, a) => {
const overToday = moment(v.date).isAfter(new Date(), 'day')
return [
...t,
{
...v,
settledIds:
v.canBeSettled === 'yes' && !overToday && v.settled === 'no'
? [v.id, ...(t[t.length - 1]?.settledIds || [])]
: [],
},
]
}, [])
.reduceRight((t, v, i, a) => {
const overToday = moment(v.date).isAfter(new Date(), 'day')
return [
...t,
{
...v,
removeSettledIds:
v.canBeSettled === 'yes' && !overToday && v.settled === 'no'
? [v.id, ...(t[t.length - 1]?.removeSettledIds || [])]
: [],
},
]
}, [])
根据场景需求格式化数据,格式化后的数据为:
[
{
canBeSettled: 'yes',
date: '2020-03-01',
id: 18,
settled: 'yes',
shareAmount: '17289.38',
tips: '200000.00 x 40% x (153/273) ',
removeSettledIds: [],
settledIds: []
},
{
canBeSettled: 'yes',
date: '2020-08-01',
id: 19,
settled: 'yes',
shareAmount: '17289.38',
tips: '200000.00 x 40% x (153/273) ',
removeSettledIds: [],
settledIds: []
},
{
canBeSettled: 'yes',
date: '2021-03-01',
id: 20,
settled: 'no',
shareAmount: '17289.38',
tips: '200000.00 x 40% x (153/273) ',
removeSettledIds: [20,21,22],
settledIds: [20]
},
{
canBeSettled: 'yes',
date: '2021-08-01',
id: 21,
settled: 'no',
shareAmount: '17289.38',
tips: '200000.00 x 40% x (153/273) ',
removeSettledIds: [21,22],
settledIds: [20,21]
},
{
canBeSettled: 'yes',
date: '2022-03-01',
id: 22,
settled: 'no',
shareAmount: '17289.38',
tips: '200000.00 x 40% x (153/273) ',
removeSettledIds: [22],
settledIds: [20,21,22]
},
{
canBeSettled: 'yes',
date: '2022-08-01',
id: 23,
settled: 'no',
shareAmount: '44835.16',
tips: '200000.00 x 40% x (153/273) ',
removeSettledIds: [],
settledIds: []
},
{
canBeSettled: 'no',
date: '2023-03-01',
id: 24,
settled: 'no',
shareAmount: '17875.46',
tips: '200000.00 x 40% x (153/273) ',
removeSettledIds: [],
settledIds: []
},
]
这样的数据结构可以轻松通过chcekbox的checked属性和onChange熟悉来控制该组件,实现联动的效果
const [settlementId, setSettlementId] = useState<number[]>([])
return (
{
mockFilter.map(value=>{
<Checkbox
disabled={value.canBeSettled === 'no' || overToday}
checked={settlementId.includes(value.id)}
onChange={(e) => {
if (e.target.checked) {
setSettlementId([...settlementId, ...value?.settledIds])
} else {
setSettlementId(settlementId.filter((item) => value?.removeSettledIds.includes(item)))
}
}}
/>
})
}
)
标签:40%,checkbox,reduce,canBeSettled,勾选,date,yes,settled,id 来源: https://www.cnblogs.com/kangxinzhi/p/16423276.html