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