Vue and React hooks implement Select batch Select, Select the number of items, Select all, reverse Select implementation comparison

React/Vue/Vue/Vue/React

Vue

This is easy to implement when using Vue. Let’s take the following data format as an example:

const dataList = [{
    id: 1.label: 'The first'}, {id: 2.label: 'Second'}, {id: 3.label: 'The third',}]Copy the code

Set (dataList[0], ‘checked’,!! Vue (dataList[0], ‘checked’) dataList[0].checked); Select the article number

const count = dataList.filter(item= > item.checked).length;
Copy the code

select all

dataList.forEach(item= > Vue.set(item, 'checked'.true));
Copy the code

The selected

dataList.forEach(item= > Vue.set(item, 'checked'.false));
Copy the code

The React to achieve a

How do you implement it in React? If you simply follow the same pattern, you’ll be disappointed.

React does not follow Vue in observer mode to handle view change logic after data is updated. It requires full data update.

The React view cannot be updated even though an element in the array is changed.

Let’s use useReducer as an example

import React, { useReducer, useMemo } from 'react';

const [state, dispatch] = useReducer({
    dataList: []},(state, reducer) = > {
    switch(reducer.type) {
     case 'update':
         return{... state, ... reducer.payload }case default:
         returnstate; }})Copy the code

React also allows us to add an extra attribute to indicate whether the React item is selected or not. We can add an extra attribute to indicate whether the React item is selected.

state.dataList[0].checked = !! state.dataList[0].checked;
dispatch({
    type: 'update'.payload: {
        dataList: state.dataList.slice()
    }
})
Copy the code

Yes, we need to add the additional step state.datalist. Slice () so that we use the new array reference. Similarly, all of the following require this additional step or similar functionality. Select the article number

const count = useMemo(() = > {
    state.dataList.filter(item= > item.checked).length
}, [state.dataList]);
Copy the code

select all

dispatch({
    type: 'update'.payload: {
        dataList: state.dataList.map(item= > ({
            ...item,
            checked: true,}}})))Copy the code

The selected

dispatch({
    type: 'update'.payload: {
        dataList: state.dataList.map(item= > ({
            ...item,
            checked: false,}}})))Copy the code

The React to achieve two

There are also many online users with the help of a storage object to achieve the above batch selection, select the number, select all, reverse selection of the function, but also a simple look at the specific implementation.

import React, { useReducer, useMemo } from 'react';

const [state, dispatch] = useReducer({
    dataList: [].checkedMap: {}, // Add a function to store selected data relationships
}, (state, reducer) = > {
    switch(reducer.type) {
     case 'update':
         return{... state, ... reducer.payload }case default:
         returnstate; }})Copy the code

{0: true} {0: true} {0: true} {0: true} {0: true} {0: true} {0: true} {0: true} {0: true}

dispatch({
    type: 'update'.payload: {
        checkedMap: {
            ...state.checkedMap,
            0:!!!!! state.checkedMap[0]}}})Copy the code

We don’t need to change the dataList data, just change the checkedMap.

Select the article number

const count = useMemo(() = > {
 Object.keys(state.checkedMap).filter(item= > state.checkedMap[item]).length
}, [state.checkedMap]);
Copy the code

select all

dispatch({
    type: 'update'.payload: {
        checkedMap: state.dataList.reduce((acc, curr) = > ({
            ...acc,
            [curr.id]: true,}), {})}})Copy the code

The selected

dispatch({
    type: 'update'.payload: {
        checkedMap: state.dataList.reduce((acc, curr) = > ({
            ...acc,
            [curr.id]: false,}), {})}})Copy the code

Results the following