Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change backgroundcolor of button in flatlist onpress

I have some buttons in my flatlist like below

const renderItem = ({ item }) => <Item name={item.name} slug={item.slug} />;

  const Item = ({ name, slug }) => {
    return (
      <TouchableOpacity
        delayPressIn={0}
        onPress={() => {
          dispatch(setLanguage(slug));
        }}
      >
        <View
          style={[
            styles.item,
            { backgroundColor: languages == slug ? "#940062" : "black" },
          ]}
        >
          <Text style={styles.title}>{name}</Text>
        </View>
      </TouchableOpacity>
    );
  };

  return (
    <SafeAreaView style={styles.container}>
      <FlatList
        horizontal={true}
        data={jsonLang}
        renderItem={renderItem}
        keyExtractor={(item) => item.id.toString()}
      />
    </SafeAreaView>
  );
};

The above code works fine, when I click it is changing the background? But background color change is delayed by 1 second. Is this the right approach to change the background color of the button?

P.S: the setlanguage is my reducer in my Redux

 setLanguage: (state, action) => {
      state.language = action.payload;
    },
like image 991
Gracie williams Avatar asked Oct 14 '25 13:10

Gracie williams


2 Answers

It works pretty fast, here's an example I created.

Perhaps the delay is in the reducer. So I artificially slowed it down.

const setLanguage = (languages) => {
  return (dispatch) => {
    setTimeout(()=>{
      dispatch({
        type: "setLanguage",
        value: languages
      });
    }, 1000) // <--------------------- delay
  };
}

but now we need to make the style apply faster. I added another field to next_languages ​​state:

const initialState = {
   languages: "1",
   next_languages: "1"
}

and modified the code like this:

const setLanguage = (languages) => {
  return (dispatch) => {

    dispatch({ // <-------------- for apply style quiqly
      type: "setNextLanguage",
      value: languages
    });

    setTimeout(()=>{
      dispatch({
        type: "setLanguage",
        value: languages
      });
    }, 1000)
  };
}

also added the costant to the component:

const fastLang = languages === next_languages 
                   ? languages 
                   : next_languages;

Finally, the styles are set like that and still quickly

{ backgroundColor: fastLang == slug ? "#940062" : "yellow" }

I think you can even get by with one variable (perhaps this contradicts the logic of work), but this is already refactoring.

I hope I could help.

like image 84
Daniil Loban Avatar answered Oct 17 '25 03:10

Daniil Loban


the 1-second delay not depending on background color changing time, but it depends on what setLanguage do?

if setLanguage change the app Language this means the all component that uses this Selector will re-render

you can split background color in separator state, this will change background fast, but change language it still takes 1-second

solution with react state just for explanation (you can use Redux)


//add this line
const [selectedLanguage, setSelectedLanguage] = react.useState(languages);


const renderItem = ({ item }) => <Item name={item.name} slug={item.slug} />;

  const Item = ({ name, slug }) => {
    return (
      <TouchableOpacity
        delayPressIn={0}
        onPress={() => {
          setSelectedLanguage(slug); //add this line, will update color immediately
          dispatch(setLanguage(slug));
        }}
      >
        <View
          style={[
            styles.item,
            //use selectedLanguage here
            { backgroundColor: selectedLanguage === slug ? "#940062" : "black" },
          ]}
        >
          <Text style={styles.title}>{name}</Text>
        </View>
      </TouchableOpacity>
    );
  };

};
like image 24
Ahmed Gaber Avatar answered Oct 17 '25 03:10

Ahmed Gaber