Bzx naga
Bzx naga

Reputation: 169

UseState doesnt change button color immediately

So I created button using looping from React useState

  const [booleanMonth,setMonth]=useState([
    {key:0,value:'January',color:'black'},
    {key:1,value:'February',color:'black'},
    {key:2,value:'March',color:'black'},
    {key:3,value:'April',color:'black'},
    {key:4,value:'May',color:'black'},
    {key:5,value:'June',color:'black'},
    {key:6,value:'July',color:'black'},
    {key:7,value:'August',color:'black'},
    {key:8,value:'September',color:'black'},
    {key:9,value:'October',color:'black'},
    {key:10,value:'November',color:'black'},
    {key:11,value:'December',color:'black'}
    ])

  const createButtonMonth = () =>{
    return (<View style={styles.containerForButtons2}>
            {
              booleanMonth.map((item,key) => 
                <View key={item.key} style={styles.buttonFilter3}><Button key={item.key} title={item.value} color={item.color}  value={item.value} 
                onPress={()=>onPressMonthFilter(item.key)}/></View>)
            }
            </View>)
    }

and then to change the button's color I'm using this function for toggle button color

  const onPressMonthFilter = (keymonth) =>{    
    if(booleanMonth[keymonth].color=='black'){
      booleanMonth[keymonth].color='green'
      setMonth(booleanMonth)
    }else{
      booleanMonth[keymonth].color='black'
      setMonth(booleanMonth)
    }
  }

the color's of pressed button doesn't change immediately but when I close some random modal or do a refresh function that I created, the button's color then will change. I don't know what happens, or how to fix it.

edit : I'm using this and it change the button immediately which is weird, and not the solution that I want, I dont want to loop

const onPressMonthFilter = (keymonth) =>{
    let monthChecked = []
    for(var i = 0 ; i<booleanMonth.length ; i ++){
      if(booleanMonth[i].key == keymonth){
          if(booleanMonth[i].color == 'green'){
            booleanMonth[i].color = 'black'
          }else{
            booleanMonth[i].color = 'green'
          }
        }
        monthChecked.push(booleanMonth[i])
      }
      setMonth(monthChecked)
}

Upvotes: 0

Views: 110

Answers (1)

Jayce444
Jayce444

Reputation: 9073

Having let monthCheck=booleanMonth does NOT create a copy of the state. It stores a reference to that state array. So mutating monthCheck mutates the state, and that causes the issues you're facing. Your easiest bet here is to use the .map method, since that returns a new array, e.g.

const onPressMonthFilter = (keymonth) =>{
      setMonth(booleanMonth.map(month => ({
          ...month,
          color: month.key === keymonth ? 'green' : 'black'
      }))
   );
}

Upvotes: 2

Related Questions