Gracie williams
Gracie williams

Reputation: 1145

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;
    },

Upvotes: 4

Views: 667

Answers (2)

Ahmed Gaber
Ahmed Gaber

Reputation: 3976

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>
    );
  };

};

Upvotes: 2

Daniil Loban
Daniil Loban

Reputation: 4381

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.

Upvotes: 2

Related Questions