'Element of list get selected slowly

i made this list of elements. when element is pressed, it's added to the state array.

in the list render, i check if element is in state array to change the background color.

it's working but , the user experience is bad, it's slow.

how can i optimise this component ?

thanks by advance

export default function ListStyleSpectacle({ navigation}) {

 

const data = [
  { key:0, value: "Art du récit"},
  { key:1,value: "Atelier"},
  { key:2, value: "Boulevard"},
  { key:3,value: "Café-théâtre"},
 
  

];

const { state, dispatch } = React.useContext(StoreContext);



const addStylesRecherches = (item) => {

 
   dispatch({
    type: "ADD_STYLES_RECHERCHES",
    payload: item,
  });


};


const removeStylesRecherches = (item) => {


dispatch({
  type: "DELETE_STYLES_RECHERCHES",
  payload: item,
});

 
};

useEffect(() => {
  console.log(state.StylesRecherches);
 

}, [state.StylesRecherches]);



return (
  <AlphabetList
    data={data}
    indexLetterStyle={{ 
      color: 'blue', 
      fontSize: 15,
    }}
    renderCustomItem={(item) => (

      <View
      key={item.key} 
      >
      <Pressable 
       
          onPress={()  =>
            {
              if(state.StylesRecherches.includes(item.value)){
                removeStylesRecherches(item);
              }else{
                addStylesRecherches(item);
              }
              //console.log(styles_list);
            }
          }
>
      <View 
      style={{
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'space-between',
        alignItems: 'center',
        padding: 10, 
        borderBottomWidth: 1,
        borderBottomColor: '#ccc',
        backgroundColor: state.StylesRecherches.includes(item.value) ? '#00cc00' : '#f2f2f2' 
      }}
      
    
      
      >
        
        <Text style={styles.listItemLabel}>{item.value}</Text>
       
      </View>
      </Pressable>
      </View>

    )}
    renderCustomSectionHeader={(section) => (
      <View style={styles.sectionHeaderContainer} key={section.key}>
        <Text style={styles.sectionHeaderLabel}>{section.title}</Text>
      </View>
    )}
  />
)


}

the part of the reducer :

case "ADD_STYLES_RECHERCHES":
     
      return {
        ...state,
        
        StylesRecherches: [...state.StylesRecherches, action.payload.value],
      };
      
      case "DELETE_STYLES_RECHERCHES" : 
      
        
        var array = [...state.StylesRecherches]; // make a separate copy of the array
        var index = array.indexOf(action.payload.value)
        if (index !== -1) {
          array.splice(index, 1);
          
        }

        return {
          ...state,
          StylesRecherches: array
        };


Solution 1:[1]

The issue is that you're iterating through the array, potentially the entire array, every time you need to select or deselect one item. Your items already have unique IDs or keys; store the selected state as an object with ID keys instead of an array.

You don't show your reducer, but I assume it's something like this:

const initialState = [];

...
    addStylesRecherches(state, action) {
      state.push(action.payload);
    },
    removeStylesRecherches(state, action) {
      state.filter(item => item.key !== action.payload.key);
    },

Instead, make your state an object, and turn IDs on and off

const initialState = {};

...
    addStylesRecherches(state, action) {
      state[action.payload.key] = true;
    },
    removeStylesRecherches(state, action) {
      state[action.payload.key] = false;
    },

Then you can rewrite your onPress function to match:

  onPress={() => {
    if (state.StylesRecherches[item.key]) {
      removeStylesRecherches(item);
    } else {
      addStylesRecherches(item);
    }
  }}

This makes gives your operation an O(1) cost instead of O(n), where n is the size of your list. Here's one blog that does a pretty good job of explaining the difference.

If your data size is really 4, this will have a barely noticeable impact, but as you go into the hundreds and thousands of items the difference will be pretty clear.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1