Why my component in react native is not being re-rendered, after there occurs change in state of the component?

101 Views Asked by At

I'm trying to get the dynamic rating and render my dynamic svg component accordingly, but after there occurs a change in state after the user select the star, the component is not being re-rendered, enter image description here

After the user selects the star from the component, the data from the state is changing but the component is not being re-rendered even there is a change in the state.

enter image description here this is the console logged value of the changed state.

this is the code of the component where logic is present

import React, {useEffect, useState} from 'react';
import {View, Text, StyleSheet, TouchableOpacity} from 'react-native';

import DirectionalShadow from './directionalShadow';

import Colors from '../res/colors';
import Images from '../res/images';
import SVGImages from '../res/images/dynamicSVG';

const RatingCard = props => {
  const [starData, setStarData] = useState([true, false, false, false, false]);

  const changeStar = data => {
    setStarData(data);
    console.log('Data logged');
    console.log(starData);
  };

  return (
    <View>
      <DirectionalShadow
        paddingBottom={1}
        shadowColor={Colors.textInputShadow}
        style={{
          borderRadius: 6,
          marginHorizontal: 16,
          marginTop: 10,
        }}>
        <View style={styles.cards}>
          <View>
            <View
              style={{
                flexDirection: 'row',
                alignItems: 'center',
                marginTop: 13,
                marginLeft: 19,
                justifyContent: 'space-between',
              }}>
              <Text
                style={{
                  color: Colors.grayLight,
                  fontSize: 14,
                  fontFamily: 'Ubuntu-Regular',
                }}>
                {props.text}
              </Text>
              <View style={{flexDirection: 'row', alignItems: 'center'}}>
                {starData.map((item, index) => (
                  <TouchableOpacity
                    key={index}
                    activeOpacity={0.75}
                    onPress={() => {
                      var temp = starData;
                      for (var i = 0; i < starData.length; i++) {
                        if (i <= index) {
                          temp.splice(i, 1, true);
                        } else {
                          temp.splice(i, 1, false);
                        }
                      }
                      changeStar(temp);
                    }}
                    style={{marginHorizontal: 5}}>
                    {item ? (
                      <SVGImages.Star color={Colors.green} />
                    ) : (
                      <SVGImages.Star />
                    )}
                  </TouchableOpacity>
                ))}
              </View>
            </View>
          </View>
        </View>
      </DirectionalShadow>
    </View>
  );
};

const styles = StyleSheet.create({
  cards: {
    height: 50,
    paddingRight: 20,
    borderRadius: 6,
    backgroundColor: Colors.textInputBackground,
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 4,
    },
    shadowOpacity: 0.3,
    shadowRadius: 4.65,
    elevation: 8,
  },
});
export default RatingCard;

1

There are 1 best solutions below

1
Michael Bahl On

You need to create a copy of your array const temp = [...starData];, if you just manipulate the array the hook won‘t recognize that something changed.

import React, {useEffect, useState} from 'react';
import {View, Text, TouchableOpacity} from 'react-native';


const ToggleSquareArray = () => {
  const [squareData, setSquareData ] = useState([true, false, false, false, false]);

  const changeSquare = data => {
    setSquareData(data);
    console.log('Data logged');
    console.log(squareData);
  };

  return (
    <View>
          <View>
            <View
              style={{
                flexDirection: 'row',
                alignItems: 'center',
                marginTop: 13,
                marginLeft: 19,
                justifyContent: 'space-between',
              }}>
              <View style={{flexDirection: 'row', alignItems: 'center'}}>
                {squareData.map((item, index) => (
                  <TouchableOpacity
                    key={index}
                    activeOpacity={0.75}
                    onPress={() => {
                      const temp = [...squareData]; // Create a copy of the array you wanna manipulate should do the trick
                      temp.splice(index, 1, !temp[index]);
                      console.log(temp);

                      changeSquare(temp);
                    }}
                    style={{marginHorizontal: 5}}>
                    {item ? (
                      <View style={{height: 50, width: 50, backgroundColor: '#ff0000'}} />
                    ) : (
                      <View style={{height: 50, width: 50, backgroundColor: '#ff00ff'}} />
                    )}
                  </TouchableOpacity>
                ))}
              </View>
            </View>
          </View>
    </View>
  );
};

export default ToggleSquareArray;