Search code examples
react-nativeecmascript-6reduxreact-reduxreact-native-sectionlist

Access data via redux for SectionList


I have a initial state as below in reducer

const initialState = {
    medicationschedule: [
        {
            date: '2019-08-27',
            medications: [
                {
                    title: '8.00 AM', 
                    data: [
                        {name:'item1', isTaken: 1,mg: '500 mg',capsules:'capsule'}, 
                        {name:'item2', isTaken: 4,mg: '2000 mg',capsules:'teaspoon'}
                ]},
                {
                    title: '12.03 PM', 
                    data: [
                        {name:'item3', isTaken: 2,mg: '500 mg',capsules:'capsule'}, 
                        {name:'item4', isTaken: 1,mg: '500 mg',capsules:'capsule'}
                ]},
                {
                    title: '3.30 PM', 
                    data: [
                        {name:'item1', isTaken: 3,mg: '500 mg',capsules:'capsule'}
                ]},
            ]
        }
    ],
    medication: [
        {
            title: '8.00 AM', 
            data: [
                {name:'item1', isTaken: 1,mg: '500 mg',capsules:'capsule'}, 
                {name:'item2', isTaken: 4,mg: '2000 mg',capsules:'teaspoon'}
        ]},
        {
            title: '12.03 PM', 
            data: [
                {name:'item3', isTaken: 2,mg: '500 mg',capsules:'capsule'}, 
                {name:'item4', isTaken: 1,mg: '500 mg',capsules:'capsule'}
        ]},
        {
            title: '3.30 PM', 
            data: [
                {name:'item1', isTaken: 3,mg: '500 mg',capsules:'capsule'}
        ]},
    ]
};

I have my class as below for the React Native SectionList.

class HomeScreen extends Component {

    state = { 
        selectedDate: Date(),
        isModalVisible: false,
     };


    render() {
        return (
            <SafeAreaView style={styles.containter}>



                <SectionList
                    renderItem={({item, index, section}) => <MedicineRow showTitle={0}  key={index} setWidth='80%' title={item.name} mg={item.mg} capsules={item.capsules} onPress={() => this.medicineRowTapped(item.name)} medstatus={item.isTaken}/>}
                    stickySectionHeadersEnabled={false}
                    renderSectionHeader={({section: {title}}) => (
                       <SectionTitle showTitle={true} title={title}/>
                    )}
                    sections={ 
                        this.props.filteredMedications
                    }
                    keyExtractor={(item, index) => item + index}
                />
            </SafeAreaView>
        )
    }
}

function mapStateToProps(state) {
    return {
        filteredMedications : state.medication
    }
}

export default connect(mapStateToProps)(HomeScreen)

The list succesfully loads if I access the medication as given in the mapStateToProps. But if I attempt to filter the data inside medictionschedule based on the date then the sectionlist doesn't load anything in the screen.

Filtering in an external function also not helping here as shown below.

medicineForTheDate = () => {
    this.props.filteredMedications.filter((schedule) => {
        if (schedule.date === '2019-08-27') {
            return schedule.medications
        }
    })
}

then inside the SectionList I would call this.medicineForTheDate()

<SectionList
    renderItem={({item, index, section}) => <MedicineRow showTitle={0}  key={index} setWidth='80%' title={item.name} mg={item.mg} capsules={item.capsules} onPress={() => this.medicineRowTapped(item.name)} medstatus={item.isTaken}/>}
    stickySectionHeadersEnabled={false}
    renderSectionHeader={({section: {title}}) => (
       <SectionTitle showTitle={true} title={title}/>
    )}
    sections={ 
        this.medicineForTheDate()
    }
    keyExtractor={(item, index) => item + index}
/>

I also tried filtering inside the mapsStateToProps but that also didn't help.

function mapStateToProps(state) {
    return {
        filteredMedications : state.medicationschedule.filter((schedule)=>{ schedule.date === '2019-08-27' })
    }
}

and then...

<SectionList
                    renderItem={({item, index, section}) => <MedicineRow showTitle={0}  key={index} setWidth='80%' title={item.name} mg={item.mg} capsules={item.capsules} onPress={() => this.medicineRowTapped(item.name)} medstatus={item.isTaken}/>}
                    stickySectionHeadersEnabled={false}
                    renderSectionHeader={({section: {title}}) => (
                       <SectionTitle showTitle={true} title={title}/>
                    )}
                    sections={ 
                        this.props.filteredMedications.medications
                    }
                    keyExtractor={(item, index) => item + index}
                />

How do I go about filtering data in this context?


Solution

  • For a start, the filter method expects a function, which takes in a parameter (the item inside the array) and returns a true (if the item should be in the filtered array) or a false (if the item should NOT be in the filtered array)

    For example:

    const arr = [1, 2, 3, 4, 5];
    
    const evenNumbersOnly = arr.filter((item) => {
      if (item % 2 === 0) {
        // Even (Want it in the list
        return true;
      } else {
        // Odd (Don't want it in the list
        return false;
      }
    });
    
    // evenNumbersOnly will now be [2, 4]
    

    Try changing your filter method and see if the filtered array is what you are expecting. From there, I believe you will be able to continue debugging if it still does not show expected results.