Why aren’t my checkboxes updating using Redux?

Tags: , , ,



I am working on a React-Native mobile app using Redux to manage the state. I have filter to manage the data displayed.

I am using Redux to manage all the data in the filters.

It’s quite simple: I click on the checkbox, it gets clicked. I click on the checkbox again (guess what), it gets unclicked. When there is a box with the value “allInclusive”, all boxes are unchecked except the “allInclusive” one.

Here’s the code for the reducer and the code for the Checkbox thing.

var comparators = {...state.comparators};
      if (!comparators[action.payload.comparator]) {
        comparators[action.payload.comparator] = {};
        comparators[action.payload.comparator][action.payload.name] = [action.payload.value];
      } else {
        if (!comparators[action.payload.comparator][action.payload.name]) {
          comparators[action.payload.comparator][action.payload.name] = [action.payload.value];
        } else {
          if (comparators[action.payload.comparator][action.payload.name].includes(action.payload.value)) {
            comparators[action.payload.comparator][action.payload.name] = comparators[action.payload.comparator][action.payload.name].filter(value => value !== action.payload.value);
          } else {
            comparators[action.payload.comparator][action.payload.name].push(action.payload.value);
          }
        }
      }
      return Object.assign({}, state, {
        comparators,
      });
import React, {Component} from 'react';
import {View, StyleSheet} from 'react-native';
import colors from '../res/colors/index';
import {CheckBox} from 'react-native-elements';
import PropTypes from 'prop-types';
import {Text} from '.';
import {style} from 'd3';
import i18n from '../i18n/i18n';
import {connect} from 'react-redux';
import * as actions from '../actions';

export class ComparatorCheckboxesContainer extends Component {
  constructor(props) {
    super(props);
    this.state = {checked: false};
  }

  checked(value) {
    if (this.props.filter.includes('allInclusive')) {
      return value === 'allInclusive';
    }
    alert(JSON.stringify(this.props.filter));
    return this.props.filter.includes(value);
  }

  render() {
    return (
      <View style={styles.checkboxesContainer}>
        <Text style={styles.checkboxesTitle}>
          {this.props.title + JSON.stringify(this.props.filter)}
        </Text>
        {this.props.options.map(option => (
          <CheckBox
            checkedIcon="check-square-o"
            uncheckedIcon="square-o"
            checkedColor={colors.principal}
            checked={this.checked(option.value)}
            onPress={() =>
              this.props.checkboxFilterChange(
                this.props.type,
                this.props.name,
                option.value,
              )
            }
            title={i18n.t(option.title)}
            containerStyle={styles.containerStyle}
            textStyle={style.textStyle}
            fontStyle={style.textStyle}
          />
        ))}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  checkboxesContainer: {
    width: '100%',
    marginLeft: 'auto',
    marginRight: 'auto',
    marginTop: 14,
  },
  checkboxesTitle: {
    fontSize: 10,
    color: colors.darkGray,
  },
  checkboxLine: {
    display: 'flex',
    flexDirection: 'row',
    justifyContent: 'flex-start',
    alignItems: 'center',
  },
  checkboxLineText: {
    fontSize: 16,
    color: colors.darkGray,
  },
  containerStyle: {
    backgroundColor: 'transparent',
    borderWidth: 0,
    marginBottom: 0,
    marginTop: 0,
    padding: 10,
  },
  textStyle: {
    marginLeft: 2,
    color: colors.darkGray,
  },
});

const mapStateToProps = ({comparators}, ownProps) => {
  if (comparators.comparators[ownProps.type] && comparators.comparators[ownProps.type][ownProps.name]) {
    return {
      filter: comparators.comparators[ownProps.type][ownProps.name],
    };
  } else {
    return {
      filter: [],
    }
  }
};

export default connect(
  mapStateToProps,
  actions,
)(ComparatorCheckboxesContainer);

Answer

Here is the reducer re-written to be immutable:

 const { comparators } = state;
  const { comparator, name, value } = action.payload;

  if (!comparators[comparator]) {
    return {
      ...state,
      comparators: {
        [comparator]: {
          [name]: value
        }
      }
    };
  } else {
    return !comparators[comparator][name]
      ? {
          ...state,
          comparators: {
            [comparator]: {
              [name]: value
            }
          }
        }
      : comparators[comparator][name].includes([value])
      ? {
          ...state,
          comparators: {
            [name]: comparators[comparator][name].filter(val2 => val2 !== value)
          }
        }
      : {
          ...state,
          comparators: {
            [comparator]: {
              [name]: [...comparators.comparator.name, value]
            }
          }
        };
  }


Source: stackoverflow