【发布时间】:2019-11-05 21:24:01
【问题描述】:
我有一个项目清单。当我将项目传递给 renderItem 组件时,一切正常。然后,当我将完全相同的项目传递给我的组件中负责渲染项目的子项时,就会出现问题。
通常它工作得非常好,但如果有多个列表项并且它上面的一个被删除,它会失去适当的功能并且变得非常错误。我认为问题在于,无论出于何种原因,一个项目假定了前一个项目的索引,孙子仍然认为它是那个项目,而不是移动到该索引中的另一个项目。
我的列表:
<FlatList
data={this.props.items}
extraData={this.props.items}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => {
return (
<TodoItem
todoItem={item}
/>
);
}}
/>
然后在 TodoItem 中,这就是我将项目传递给孙子的方式:
class TodoItem extends Component {
render() {
const todoItem = this.props.todoItem;
return (
<View>
<ItemSwipeRow
item={todoItem}
completeItem={this.props.deleteTodo}
>
然后在 itemSwipeRow 这就是我接收道具的方式
import React, { Component } from 'react';
import { Animated, StyleSheet, View } from 'react-native';
import { RectButton } from 'react-native-gesture-handler';
import Swipeable from 'react-native-gesture-handler/Swipeable';
import { Ionicons, MaterialCommunityIcons } from '@expo/vector-icons';
import { connect } from 'react-redux';
import { openNotesModal, openDateModal } from '../actions';
const AnimatedIcon = Animated.createAnimatedComponent(Ionicons);
class ItemSwipeRow extends Component {
constructor(props) {
super(props);
this.item = props.item;
}
renderLeftActions = (progress, dragX) => {
const trans = dragX.interpolate({
inputRange: [0, 50, 100, 101],
outputRange: [-20, 0, 0, 1],
});
return (
<RectButton style={styles.leftAction}>
<AnimatedIcon
name='md-checkmark'
color='#28313b'
size={45}
style={[
styles.actionText,
{
transform: [{ translateX: trans }],
},
]}
/>
</RectButton>
);
};
renderRightAction = (action, name, color, x, progress) => {
const trans = progress.interpolate({
inputRange: [0, 1],
outputRange: [x, 0],
});
const pressHandler = () => {
action(this.item);
};
return (
<Animated.View style={{ flex: 1, transform: [{ translateX: trans }] }}>
<RectButton
style={[styles.rightAction, { backgroundColor: color }]}
onPress={pressHandler}
>
<MaterialCommunityIcons
name={name}
size={35}
color='#28313b'
/>
</RectButton>
</Animated.View>
);
};
renderRightActions = progress => (
<View style={styles.rightSwipeButtons}>
{this.renderRightAction(
this.props.openDateModal, 'calendar', '#B8B8F3', 192, progress
)}
{this.renderRightAction(
this.props.openNotesModal, 'pencil', '#F0A202', 128, progress
)}
{this.renderRightAction(
this.props.openDateModal, 'bell', '#db5461', 64, progress
)}
</View>
);
updateRef = ref => {
this.currItem = ref;
};
close = () => {
if (this.currItem !== null) { this.currItem.close(); }
};
onSwipeableLeftOpen = () => {
this.props.completeItem();
this.close();
}
onSwipeableRightWillOpen = () => {
console.log(this.item.text); //tried passing in item here but didn't
} //work, instead of console logging on call it did every item @ start
// then none when it was suppose to log it.
render() {
const { children } = this.props;
const { item } = this.props;
return (
<Swipeable
ref={this.updateRef}
friction={2}
leftThreshold={70}
rightThreshold={40}
renderLeftActions={this.renderLeftActions}
renderRightActions={this.renderRightActions}
onSwipeableLeftOpen={this.onSwipeableLeftOpen}
onSwipeableRightWillOpen={this.onSwipeableRightWillOpen}
>
{children}
</Swipeable>
);
}
}
const styles = StyleSheet.create({
leftAction: {
flex: 1,
backgroundColor: '#82ff9e',
justifyContent: 'center',
},
rightAction: {
alignItems: 'center',
flex: 1,
justifyContent: 'center',
},
rightSwipeButtons: {
width: 192,
flexDirection: 'row'
}
});
export default connect(null, { openNotesModal, openDateModal })(ItemSwipeRow);
我的控制台日志证明并不总是呈现正确的项目。该项目的删除工作正常,但是如果一个项目被删除并且它下面有东西,那么它下面的项目假定它是刚刚删除的项目。
对此的任何帮助将不胜感激,如果需要,我可以提供更多代码。
删除项目的代码:
action that's sent on left swipe–
export const removeTodo = (item) => {
return {
type: REMOVE_TODO,
id: item.id
};
};
reducer action goes to–
case REMOVE_TODO: {
const newList = state.todos.filter(item => item.id !== action.id);
for (let i = 0, newId = 0; i < newList.length; i++, newId++) {
newList[i].id = newId;
}
return {
...state,
todos: newList
};
}
【问题讨论】:
-
您的数据中没有自然键吗?如果是,您可以将其用作平面列表中的键吗?
-
每个项目都有一个id,你是说我应该把它作为索引吗?
-
是的,这样会更好,keyExtractor={(item) => item.id}
-
这也可以解决您遇到的问题。
-
好的没问题,这样还是不错的。
标签: reactjs react-native