'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 |
