更新Redux中维护的对象数组时,本机FlatList呈现数据出现问题

时间:2020-03-04 11:19:04

标签: react-native redux react-native-flatlist

我正在FlatList中加载动态表单。我应该根据条件在UI元素(如TextInput,checkbox等)中添加几行。例如,我有一个下拉列表,当我选择一个值时,我必须添加一个带有按钮的行,并在选择另一个值时删除该行。

我的问题是,每当我在下拉列表中选择一个值以添加带有按钮的行时,FlatList都会添加重复的行,并且在调试它们时它们在我的数组中不可见。我正在使用Redux来管理应用程序状态并在reducers中更新数组。

我必须使用Redux进行状态管理,在FlatList中的数组中显示对象,而没有任何重复。

代码:

<FlatList
    key={Math.floor(Math.random())}
    ref={(ref) => { this.flatListRef = ref; }}
    data={this.state.mainArray}
    renderItem={this._renderItem}
    keyExtractor={({ item, id }) => String(id)}
    extraData={this.prop}
    keyboardDismissMode="on-drag"
   showsVerticalScrollIndicator={false}
   scrollEnabled={true}
   removeClippedSubviews={false}
   scrollsToTop={false}
   initialNumToRender={100}
  />

componentWillReceiveProps(nextProps) {
      this.setState({mainArray: nextProps.mainArray});

}

在Reducer中更新数组:

case VALIDATE_DEPENDENCY: {
    // adding or removing dependency questions
    let dependingQues = [];
    let formArrayTemp = [...state.mainArray];
    let exists;
    // console.log("formArrayTemp123", formArrayTemp);
    if (action.item.isDependentQuestion) {
        if (action.item.dependentQuestionsArray.length > 0) {
            let dependent_ques = action.item.dependentQuestionsArray[0];
            state.depending_questions_array.filter((obj, id) => {
                if (JSON.stringify(obj.key_array) === JSON.stringify(dependent_ques.key)) {
                    dependingQues.push(obj);
                }
            });
            // console.log("dependingQues123", dependingQues);
            if (dependent_ques.answer === action.item.answer) {
                dependingQues.map((obj, id) => {
                    exists = formArrayTemp.filter((res, idx) => {
                        if (JSON.stringify(res.key_array) === JSON.stringify(obj.key_array)) {
                            return res;
                        }
                    });
                    // console.log("exists123", exists);
                    if (exists.length === 0) {
                        formArrayTemp.splice(action.index + id + 1, 0, obj);
                        // console.log("mjkgthbythyhy", action.index + id + 1);
                    }
                });
            }
            else {
                let objIndex = formArrayTemp.findIndex(obj => JSON.stringify(obj.key_array) === JSON.stringify(dependent_ques.key));
                if (objIndex !== -1) {
                    formArrayTemp[objIndex].answer = "";
                    formArrayTemp[objIndex].borderColor = "black";
                    formArrayTemp.splice(objIndex, 1);
                    // console.log("frtg6hyjukiu", formArrayTemp);
                }
            }
        }
    }
    // adding or removing dependent sections
    let dependentSections = [];
    let tempArr = [];
    let count = 0;
    if (action.item.isDependent) {
        if (action.item.dependentArray.length > 0) {
            let dependent_section = action.item.dependentArray[0];
            state.dependent_sections_array.filter((obj, id) => {
                if (obj.section_id === dependent_section.section_id) {
                    dependentSections.push(obj);
                }
            });
            // console.log("dependentSections123", dependentSections);
            let lastIndex;
            formArrayTemp.filter((res, id) => {
                if (action.item.section_id === res.section_id && res.dependentArray &&
                    JSON.stringify(action.item.dependentArray) === JSON.stringify(res.dependentArray)) {
                    tempArr.push(res);
                    lastIndex = formArrayTemp.FindLastIndex(a => a.section_id === res.section_id);
                }
            });
            // console.log("lastIndex123", lastIndex);
            tempArr.map((obj, id) => {
                if (obj.answer === obj.dependentArray[0].answer) {
                    count++;
                }
            });
            if (dependent_section.answer === action.item.answer) {
                dependentSections.map((obj, id) => {
                    if (formArrayTemp.contains(obj) === false) {
                        formArrayTemp.splice(lastIndex + id + 1, 0, obj);
                        // console.log("cfrererfre", formArrayTemp);
                    }
                });
            }
            else {
                let countTemp = [];
                if (count === 0) {
                    let countTemp = [];
                    dependentSections.filter((res, id) => {
                        if (formArrayTemp.contains(res) === true) {
                            formArrayTemp.filter((obj, idx) => {
                                if (obj.section_id === res.section_id) {
                                    obj.answer = "";
                                    obj.borderColor = "black";
                                    countTemp.push(obj);
                                }
                            });
                        }
                    });
                    let jobsUnique = Array.from(new Set(countTemp));
                    formArrayTemp = formArrayTemp.filter(item => !jobsUnique.includes(item));
                    // console.log("frefrefre123", formArrayTemp);
                    // return { ...state, mainArray: [...formArrayTemp] }
                }
            }
        }
    }
    console.log("formArray123", formArrayTemp);
    formArrayTemp.sort((a, b) => {
        return a.posiiton - b.position;
    });
    return { ...state, mainArray: formArrayTemp }
};

更新

研究了这个问题之后,我在GitHub上遇到了这个issue #24206。上面写着:

有些事情您在这里做得不太正确。每次运行render函数时,您都会为数据创建一个新的数组对象,因此React每次都必须重新渲染整个列表,您的renderItem函数和keyExtractor函数也会在每次重新渲染时都进行重新绘制,因此FlatList必须重新运行。您还将索引用作索引键,这意味着一旦移动任何内容,它将在该时间点后重新呈现所有内容。我建议您查看重新运行事物(数组,函数,对象)时什么/不改变,以及为什么keyExtractor对于减少重新渲染很重要。

所以我尝试评论KeyExtractor的{​​{1}}道具,问题得到解决。但这以另一种形式引起了问题。我该如何解决?

0 个答案:

没有答案