通过 redux 访问 SectionList 的数据

Access data via redux for SectionList

我在 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'}
        ]},
    ]
};

我的 class 下面是 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)

如果我访问 mapStateToProps 中给出的药物,列表将成功加载。但是,如果我尝试根据日期过滤 medictionschedule 内的数据,则部分列表不会在屏幕上加载任何内容。

在外部函数中进行过滤也无济于事,如下所示。

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

然后在 SectionList 里面我会调用 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}
/>

我也尝试在 mapsStateToProps 中进行过滤,但这也没有帮助。

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

然后...

<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}
                />

如何在这种情况下过滤数据?

试试这个!

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

你很接近,但你的每一种方法都有一些小错误。

在使用外部方法的方法 1 中,您没有 return 从方法中获取值,并且 filter 没有像您预期的那样工作。数组上的 filter 方法将 return 另一个只包含原始数组元素的数组,其中过滤子句 return 是一个真值。因此,在您的示例中,即使您 return schedule.medications 您仍然以包含原始数据的数组结束。我认为与您的意图最相似的代码是:

medicineForTheDate = () => {
    const matchingMedications = this.props.filteredMedications.filter((schedule) => {
        return schedule.date === '2019-08-27'; // filter if dates are equal
    })
    if (matchingMedications.length) { // if we have a result
        return matchingMedications[0].medications;
    }
    // decide about a default value if there is no match
}

也就是说我认为 for 循环更清楚:

medicineForTheDate = () => {
    const {filteredMedications} = this.props;
    for (let i=0; i < filteredMedications.length; i++) {
      const schedule = filteredMedications[i];
      if (schedule.date === '2019-08-27') {
         return schedule.medications
      }
    }
    // decide if you want to return a different value if no match is found
}

对于第二种情况,您有类似的错误 - 不正确地使用过滤器,实际上没有 returning 来自过滤器的值。再次类似

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

只要您考虑到 filteredMedications 在您的组件中未定义,在这种情况下,如果日期不匹配,

就会工作。

首先,filter 方法需要一个函数,该函数接受一个参数(数组中的项目)和 returns true(如果该项目应该在过滤数组中) 或 false(如果该项目不应在过滤后的数组中)

例如:

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]

尝试更改您的 filter 方法并查看过滤后的数组是否符合您的预期。从那里,如果仍然没有显示预期的结果,我相信您将能够继续调试。