Фильтр FlatList, показывающий дополнительные данные - PullRequest
0 голосов
/ 15 февраля 2020

У меня есть FlatList, в котором я отображаю некоторые задания, которые я получаю с моего сервера. Я недавно добавил фильтры и хочу отображать отфильтрованный список заданий всякий раз, когда пользователь выбирает фильтр. Я использую extraData в моем FlatList, чтобы сигнализировать о том, что я хочу, чтобы он был повторно обработан. Перерисовывает, но с ошибкой.

Моя проблема заключается в следующем:

  1. Пользователь применяет фильтр A, который приводит к списку заданий X.
  2. Затем пользователь отменяет выбор фильтра A и выбирает фильтр B. Это должно привести к списку заданий Y. Однако в моем случае задания Y и X (из предыдущего фильтра) отображаются на экране.

проблема с FlatList. Я добавил ведение журнала и увидел, что отправляю правильный список заданий (Y), но FlatList объединяет это с заданиями из предыдущего фильтра.

У меня есть функция formatJobsData, которая вызывается всякий раз, когда применяется фильтр:

formatJobsData = (jobsData) => {
    var json = JSON.parse(JSON.stringify(jobsData));


    if (this.state.isFilterActive == true ) {

        if (filters.driving.under15Pressed == true) {
            for (var _id in json) {
                if (json[_id].duration_driving != null && json[_id].duration_driving.value > 899)
                    delete json[_id];
            }
        }

        //additional logic for determining the list of jobs to be displayed.
    }

    for (var _id in json) {

        sort_array.push({
            _id: count++,
            jobtitle: json[_id].jobtitle,
            company: json[_id].company,
            duration_driving_value: json[_id].duration_driving.value,
            duration_transit_value: json[_id].duration_transit.value,
            duration_walking_value: json[_id].duration_walking.value,
            duration_driving: json[_id].duration_driving.text,
            duration_transit: json[_id].duration_transit.text,
            duration_walking: json[_id].duration_walking.text,
            date: json[_id].date,
            formatedDescription: json[_id].formatedDescription,
            applyUrl: json[_id].applyUrl
        });
    }

    return sort_array;
}

Затем я отправляю список отфильтрованных заданий моей функции RenderJobs, которая отвечает за отображение заданий:

    return(
        <ScrollView contentContainerStyle={styles.bkg}>

            <RenderJobs 
                    jobsData={this.formatJobsData(this.state.jobs)}
                    isLoading={this.props.jobs.isLoading}
                    errMess={this.props.jobs.errMess}
                    navigation={this.props.navigation}
                    sortOrder={this.state.selectedSortOrder}
                    sortArray={this.state.sortArray}
                    sortOrFilterOrderProps={this.state.sortOrFilterApplied}
                    />
        )
    }

В RenderJobs я обрабатывать данные и передавать их в FlatList.

function RenderJobs(props) {

var mapObj = {
    mins:"min",
    hours:"ore",
    hour: "ora"
};
const renderJobItem = ({item}) => {
    //handle data
    return (
        <Panel 
            jobTitle={item.jobtitle}
            company={item.company}
            durationCar={durationCarApi}
            durationTram={durationPublicTransportApi}
            durationWalking={durationWalkApi}
            dateAdded={formattedApiDate}
            onPress={() => 
                {
                props.navigation.navigate('JobDetails', {
                    jobTitle: item.jobtitle,
                    company: item.company,
                    durationCar: durationCarApi,
                    durationTram: durationPublicTransportApi,
                    durationWalking: durationWalkApi,
                    jobDescription: formattedJobDescription,
                    applyUrl: item.applyUrl
            })
                }
            }/>
    );
}

    return (
        <FlatList 
                data={props.jobsData}
                extraData={props.sortOrFilterOrderProps}
                renderItem={renderJobItem}
                keyExtractor={(item, index) => item._id}
                style={{marginTop: 10}}
                />
    );

}

Любая помощь будет высоко оценена!

1 Ответ

0 голосов
/ 01 марта 2020

Проблема заключалась в том, что в моем PanelComponent я сохранял реквизиты в состоянии в конструкторе, а затем использовал это состояние для рендеринга. Так как состояние не изменилось, очевидно, что отображаемые данные не обновлялись.

Я остановил сохранение реквизитов в состоянии компонента и использовал их непосредственно в методе рендеринга для отображения данных. Итак, я пошел от:

class Panel extends Component{
    constructor(props){
        super(props);

        this.state = {
        onPress: props.onPress,
        jobTitle: props.jobTitle,
        company: props.company,
        durationCar: props.durationCar,
        durationTram: props.durationTram,
        durationWalking: props.durationWalking,
        dateAdded: props.dateAdded,
    };

    this.icons = {     
        'car'    : require('../../assets/car.png'),
        'tram'    : require('../../assets/tram.png'),
        'walk'    : require('../../assets/walk.png')
    };

render(){
    return (
        <View style={styles.container}>
                <TouchableHighlight 
                    onPress={this.state.onPress}
                    underlayColor={colors.white}>
                    <View style={styles.cardStyle}>
                        <Text style={styles.jobTitleStyle}>{this.**state**.jobTitle}</Text>
                        <Text style={styles.companyStyle}>{this.**state**.company}        </Text>
//more code to display stuff
        );
}
}

К этому:

class Panel extends Component{
    constructor(props){
        super(props);

        this.state = {
        onPress: props.onPress
    };

    this.icons = {     
        'car'    : require('../../assets/car.png'),
        'tram'    : require('../../assets/tram.png'),
        'walk'    : require('../../assets/walk.png')
    };

render(){
    return (
        <View style={styles.container}>
                <TouchableHighlight 
                    onPress={this.state.onPress}
                    underlayColor={colors.white}>
                    <View style={styles.cardStyle}>
                        <Text style={styles.jobTitleStyle}>{this.**props**.jobTitle}</Text>
                        <Text style={styles.companyStyle}>{this.**props**.company}        </Text>
//more code to display stuff
        );
}
}
...