函数在状态数组上看到旧值

时间:2019-10-15 11:41:03

标签: javascript reactjs react-native react-native-android

我正在尝试制作测试应用,只是一个简单的通讯录。

我快完成了,但是现在我在从FlatList中选择项目时遇到了一个问题。

当我长按一个联系人时,它将触发onLongPress函数,它将该联系人标记为已选择并使用this.setState({selectedContacts})保存所选联系人的列表

问题是当我点击某个联系人时,如果已经选择了一个联系人,则应继续选择该联系人;如果未选择任何联系人,则应进入该联系人详细信息屏幕。

问题在于onPress函数this.state.selectedContacts.length上始终为0。

onPress(contact) {
  console.log("Contacts Selected:",this.state.selectedContacts.length);
  if (this.state.selectedContacts.length < 1) {
    console.log("navigating");
    this.props.navigation.navigate('ContactDetails', {
      id: `${contact.id}`,
    });
  } else {
    this.toggleSelection(contact);
  }
  console.log("onPress",this.state.selectedContacts);
}

onLongPress(contact) {
  toggleSelection(contact);
  console.log("onLongPress",this.state.selectedContacts);
}

toggleSelection(contact) {
    contact.isSelected = !contact.isSelected;

    selectedContacts = [];

    this.state.contacts.map(function(contact){
      if (contact.isSelected){
        selectedContacts[contact.id] = contact.facebook_url;
      }
    });

    this.setState({selectedContacts});
}

<TouchableOpacity style={listItemStyle}
                  onPress={() => this.onPress(contact)} 
                  onLongPress={() => this.onLongPress(contact)}>
    <Image source={{ uri: contact.icon }} style={styles.itemListAvatar} />
    <View style={styles.itemListText}>
        <Text style={styles.itemListName}>
            {contact.name}
        </Text>
        <Text style={styles.itemListDescription}>
            {contact.description}
        </Text>
    </View>
</TouchableOpacity>

2 个答案:

答案 0 :(得分:2)

在这里,您模糊地使用数组作为对象:

typeof [] === 'object

要将项目添加到javascript数组,必须使用Array.prototype.push方法,否则长度不会改变(不完全正确,请参见下面的详细信息)。

问题是JS newKeyThatMayNotBeANumber,因此您可以编写arr [newKeyThatMayNotBeANumber]将newKeyThatMayNotBeANumber属性添加到arr对象,但是这样做不会总是增加数组的长度。

因为JS太好了,所以如果{}可解释为数字(即:是数字或数字的base10字符串表示形式),它将实际上改变数组的大小。

但否则将无法这样做。因此,使用实际对象(const arr = []; console.log(arr.length) => 0 arr['128'] = 'a'; console.log(arr) => [empty × 128, "a"] console.log(arr.length) => 129 arr['bar'] = 'a'; console.log(arr) => (129) [empty × 128, "a", bar: "a"] console.log(arr.length) => 129 )进行键处理,使用数组变异方法(或严格的数字索引访问)进行数组是一个好习惯。

Chrome中的控制台输出表明了这种问题:

 this.state.dataDate = "2019-10-15 11:59:27";
 var cacheDateUTC = new Date(this.state.dataDate + "Z");
 var cacheDateLocal = cacheDateUTC.toLocaleString();

 // Chrome browser
 -- "10/15/2019, 3:19:54 PM"

 // Safari browser
 -- "Invalid Date"

也就是说,contact.id总是一个数字吗?

答案 1 :(得分:-1)

React依赖于引用。因此,当您更改状态然后尝试设置状态时,什么也不会发生。有一条规则-状态应该是不变的。尝试创建数组的新实例,而不是突变旧实例:

const newSelectedContacts = selectedContacts.slice();
newSelectedContacts[contact.id] = contact.facebook_url;

this.setState({selectedContacts: newSelectedContacts});

您的.map()调用看起来也没用-您只是多次将相同的值分配给同一数组项=)