javascript - React Native - 从数组中删除对象

标签 javascript arrays react-native state splice

我有一个显示联系人列表的模态框。 onPress,联系人会动态添加到 View 中。 如果已添加联系人,则在第二次按下时我想将其从 View 中删除。为此,我使用拼接修改包含触点的状态/数组,但它会立即删除所有触点。

我还尝试更新“添加”图标的状态。如果已添加联系人,则“添加”图标图像应成为事件图标。

不确定我做错了什么?

这是打开的模态框:

enter image description here

我的代码:

    import React, {Component} from 'react'
    import {
        Text,
        View,
        ListView,
        ScrollView,
        StyleSheet,
        Image,
        TouchableHighlight,
        TextInput,
        Modal,
    } from 'react-native'


    const friends = new ListView.DataSource({
        rowHasChanged: (r1, r2) => r1 !== r2
    }).cloneWithRows([
        {
            id: 1,
            firstname: 'name1',
            surname: 'surname1',
            image: require('../images/friends/avatar-friend-01.png')
        },
        {
            id: 2,
            firstname: 'name2',
            surname: 'surname2',
            image: require('../images/friends/avatar-friend-02.png')
        },
        {
            id: 3,
            firstname: 'name3',
            surname: 'surname3',
            image: require('../images/friends/avatar-friend-03.png')
        },
    ])


    class AppView extends Component {
        state = {
            isModalVisible: false,
            contactsPicked: [],
            friendsState: {},
        }

        setModalVisible = visible => {
            this.setState({isModalVisible: visible})
        }

        pickContact = (friend) => {
            if(this.state.contactsPicked.indexOf(friend) < 0){
                var tempFriendsState = this.state.friendsState
                tempFriendsState[friend.id] = true

                this.setState({
                    contactsPicked: [ ...this.state.contactsPicked, friend],
                    friendsState: tempFriendsState,
                })
            }
            else{
                let index = this.state.contactsPicked.indexOf(friend)
                let nextContacts = this.state.contactsPicked
                nextContacts.splice(index,1)
                let tempFriendsState = this.state.friendsState
                tempFriendsState[friend.id] = false

                this.setState({
                    contactsPicked: nextContacts,
                    friendsState: tempFriendsState,
                })
            }
        }

        removeContact = (friend) => {
            let index = this.state.contactsPicked.indexOf(friend)
            let nextContacts = this.state.contactsPicked
            nextContacts.splice(index,1)

            this.setState({
                contactsPicked: nextContacts,
            })
        }

        _renderAddFriendTile = () => {
           return(
                <View style={[styles.step, styles.stepThree]}>
                    <View style={{flex:1}}>
                        <Text style={styles.heading}>Friend tile</Text>
                    </View>

                    {this.state.contactsPicked.length > 0 && (
                        <TouchableHighlight onPress={() => {this.removeContact(this.state.contactsPicked)}}>
                            <View>
                                {this.state.contactsPicked.map((contact,index) => (
                                    <View key={index} style={[styles.row, styles.friendRow]}>
                                        <Image source={contact.image} style={styles.friendIcon}></Image>
                                        <Text style={styles.name}>{contact.firstname} </Text>
                                        <Text style={styles.name}>{contact.surname}</Text>

                                        <View style={styles.roundIconContainer}>
                                            <View style={styles.roundIcon}>
                                                <View style={[styles.removeButton, styles.buttonSmall]}>
                                                    <Image source={require('../images/button-cross-small.png')} style={styles.crossIconSmall}></Image>
                                                </View>
                                            </View>
                                        </View>
                                    </View>
                                ))}
                            </View>
                        </TouchableHighlight>
                    )}

                    <TouchableHighlight style={styles.addFriendButtonContainer} onPress={() => {this.setModalVisible(true)}}>
                        <View style={styles.addFriendButton}>
                            <Text style={styles.addFriendButtonText}>Add friends</Text>
                        </View>
                    </TouchableHighlight>
                </View>
            )
        }

        render(){
            return (
                <ScrollView style={styles.container}>
                    <Modal
                        animationType={'fade'}
                        transparent={true}
                        visible={this.state.isModalVisible}
                    >
                        <View style={styles.addFriendModalContainer}>
                            <View style={styles.addFriendModal}>
                                <TouchableHighlight onPress={() => {this.setModalVisible(false)}}>
                                    <View>
                                        <Text>Close</Text>
                                    </View>
                                </TouchableHighlight>
                                <ListView
                                    dataSource={friends}
                                    renderRow={(friend) => {
                                        return (
                                            <FriendRow
                                                friend={friend}
                                                pickContact={this.pickContact}
                                                isSelected={this.state.friendsState[friend.id]}
                                            />
                                        )
                                    }}
                                />
                            </View>
                        </View>
                    </Modal>

                    {this._renderAddFriendTile()}
                </ScrollView>
            )
        }
    }

    class FriendRow extends Component {
        render(){
            return(
                <TouchableHighlight onPress={() => {this.props.pickContact(this.props.friend)}}>
                    <View style={[styles.row, styles.friendRow]}>
                        <Image source={this.props.friend.image} style={styles.friendIcon}></Image>
                        <Text style={styles.name}>{this.props.friend.firstname} </Text>
                        <Text style={styles.name}>{this.props.friend.surname}</Text>

                        <View style={styles.roundIconContainer}>
                            <View style={styles.roundIcon}>
                                <View style={this.props.isSelected ? [styles.buttonActive, styles.buttonSmall]: [styles.modalButtonInactive, styles.buttonSmall]}>
                                    <Image source={this.props.isSelected && require('../images/button-tick-small-on.png')} style={styles.buttonTickSmall}></Image>
                                </View>
                            </View>
                        </View>
                    </View>
                </TouchableHighlight>
            )
        }
    }

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#e1e1e1'
    },
    row: {
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'center',
    },
    step: {
        backgroundColor: '#ffffff',
        borderRadius: 4,
        borderLeftWidth: 5,
        flex: 1,
        marginLeft: 10,
        marginRight: 10,
        marginBottom: 10,
        paddingLeft: 15,
        paddingRight: 10,
        paddingTop: 15,
        paddingBottom: 20,
        shadowOffset: {
            width: 0,
            height: 2,
        },
        shadowRadius: 2,
        shadowOpacity: 0.2,
        shadowColor: '#000000',
    },
    stepThree: {
        borderLeftColor: '#ffbd18',
    },
    heading: {
        textAlign: 'center',
        fontWeight: 'bold',
        fontSize: 15,
        color: '#333333',
    },
    addFriendButtonContainer: {
        marginTop:15,
        flex:1,
        alignItems: 'center',
        justifyContent: 'center',
        flexDirection: 'row',
    },
    addFriendButton: {
        backgroundColor: '#ffbd18',
        width: 270,
        borderRadius: 4,
        paddingTop: 15,
        paddingBottom: 15,
    },
    addFriendButtonText: {
        color: '#ffffff',
        fontSize: 18,
        fontWeight: 'bold',
        textAlign: 'center',
    },
    pickContainer: {
        flex:1,
        flexDirection: 'row',
        justifyContent: 'space-between',
        alignItems: 'center',
        borderRightWidth: 1,
    },
    pickWrapper: {
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'space-around',
        alignItems: 'center',
        marginTop: 10,
    },
    buttonBig: {
        height: 60,
        width: 60,
        borderRadius: 30,
    },
    buttonSmall: {
        height: 20,
        width: 20,
        borderRadius: 10,
    },
    buttonActive: {
        backgroundColor: '#fd6769',
        alignItems: 'center',
        justifyContent: 'center',
    },
    buttonInactive: {
        backgroundColor: '#eeeeee',
        alignItems: 'center',
        justifyContent: 'center',
    },
    removeButton:{
        backgroundColor: '#cccbcb',
        alignItems: 'center',
        justifyContent: 'center',
    },
    modalButtonInactive: {
        backgroundColor: '#ffffff',
        borderWidth: 1,
        borderColor: '#eeeeee',
    },
    buttonTickBig: {
        width: 34,
        height: 28,
    },
    buttonTickMinusBig: {
        width: 18,
        height: 8,
    },
    buttonTickSmall: {
        width: 12,
        height: 10,
    },
    crossIconSmall: {
        width: 12,
        height: 10,
    },
    pickText: {
        color: '#c7c7c7',
        fontWeight: 'bold',
    },
    addFriendModalContainer: {
        flex: 1,
    },
    addFriendModal: {
        flex: 1,
        backgroundColor: '#ffffff',
        borderRadius: 4,
        paddingLeft: 15,
        paddingRight: 10,
        paddingTop: 20,
        paddingBottom: 20,
        shadowOffset: {
            width: 0,
            height: 2,
        },
        shadowRadius: 2,
        shadowOpacity: 0.2,
        shadowColor: '#000000',
        textAlign: 'center',
    },
    nextButtonContainer: {
        marginBottom: 20,
    },
    nextButton: {
        textAlign:'right',
    },
    friendRow: {
        height: 60,
        borderBottomWidth: 1,
        borderBottomColor: '#eeeeee',
        justifyContent: 'flex-start',
    },
    friendIcon: {
        width: 50,
        height: 50,
        marginRight: 25,
    },
    roundIconContainer:{
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'flex-end',
        alignItems: 'flex-end',
    },
    roundIcon: {
        height: 20,
        width: 20,
        borderRadius: 10,
        backgroundColor: '#fd6769',
        justifyContent: 'center',
        alignItems: 'center',
        marginRight: 20,
    },
})

export default AppView

最佳答案

使用拼接,但会立即删除所有触点。

因为你使用的拼接方法是错误的。检查方法获取的参数。 http://www.w3schools.com/jsref/jsref_splice.asp

[ ...this.state.contactsPicked, this.state.contactsPicked.splice(friend)]

这也不如您所期望的那样工作。它合并两个数组。

var parts = ['shoulders', 'knees'];
var parts2 = ['shoulders'];
var lyrics = [ ...parts, ...parts2 ];

console.log(lyrics)

看来你不必使用扩展运算符([...arr,.arr2]), 你可以简单地做到这一点

  1. 由于每次模态可见性发生变化时它都会重新创建子组件,即使您更改父组件的状态,它也不会重新渲染子组件,因此您需要保留子组件的内部状态
  2. 此外,您的 _renderAddFriendTile 方法也运行错误。什么时候 你仔细看看你就会意识到你的错误。
  3. 不要忘记用我的测试图标更改您的图标
<小时/>
  class AppView extends Component {
  constructor(props) {
      super(props);
      this.state = {
        isModalVisible: false,
        contactsPicked: [],
        friendsState: {},
      }
  }

    setModalVisible = visible => {
        this.setState({isModalVisible: visible})
    }

    pickContact = (friend) => {
        if(this.state.contactsPicked.indexOf(friend) < 0){
            var tempFriendsState = this.state.friendsState
            tempFriendsState[friend.id] = true

            this.setState({
                contactsPicked: [ ...this.state.contactsPicked, friend],
                friendsState: tempFriendsState,
            })
        }
        else{
            let index = this.state.contactsPicked.indexOf(friend)
            let nextContacts = this.state.contactsPicked
            nextContacts.splice(index,1)
            let tempFriendsState = this.state.friendsState
            tempFriendsState[friend.id] = false

            this.setState({
                contactsPicked: nextContacts,
                friendsState: tempFriendsState,
            })
        }
    }

    removeContact = (friend) => {
        let index = this.state.contactsPicked.indexOf(friend)
        let nextContacts = this.state.contactsPicked
        let tempFriendsState = this.state.friendsState
        tempFriendsState[friend.id] = false
        nextContacts.splice(index,1)
        console.log('removeContact'+friend.id);
        this.setState({
            contactsPicked: nextContacts,
            friendsState: tempFriendsState,
        })
    }

    _renderAddFriendTile = () => {
       return(
            <View style={[styles.step, styles.stepThree]}>
                <View style={{flex:1}}>
                    <Text style={styles.heading}>Friend tile</Text>
                </View>

                { (this.state.contactsPicked.length) > 0 ?
                  this.state.contactsPicked.map((contact,index) => (
                              <TouchableHighlight onPress={() => {this.removeContact(contact)}}>
                                  <View>
                                <View key={index} style={[styles.row, styles.friendRow]}>
                                    <Image source={contact.image} style={styles.friendIcon}></Image>
                                    <Text style={styles.name}>{contact.firstname} </Text>
                                    <Text style={styles.name}>{contact.surname}</Text>

                                    <View style={styles.roundIconContainer}>
                                        <View style={styles.roundIcon}>
                                            <View style={[styles.removeButton, styles.buttonSmall]}>
                                                <Image source={require('./images/redtree.jpg')} style={styles.crossIconSmall}></Image>
                                            </View>
                                        </View>
                                    </View>
                                </View>
                                </View>
                            </TouchableHighlight>
                            ))
                            : null

                }

                <TouchableHighlight style={styles.addFriendButtonContainer} onPress={() => {this.setModalVisible(true)}}>
                    <View style={styles.addFriendButton}>
                        <Text style={styles.addFriendButtonText}>Add friends</Text>
                    </View>
                </TouchableHighlight>
            </View>
        )
    }

    render(){
        return (
            <ScrollView style={styles.container}>
                <Modal
                    animationType={'fade'}
                    transparent={true}
                    visible={this.state.isModalVisible}
                >
                    <View style={styles.addFriendModalContainer}>
                        <View style={styles.addFriendModal}>
                            <TouchableHighlight onPress={() => {this.setModalVisible(false)}}>
                                <View>
                                    <Text>Close</Text>
                                </View>
                            </TouchableHighlight>
                            <ListView
                                dataSource={friends}
                                renderRow={(friend) => {
                                    return (
                                        <FriendRow
                                            friend={friend}
                                            pickContact={this.pickContact}
                                            isSelected={this.state.friendsState[friend.id]}
                                        />
                                    )
                                }}
                            />
                        </View>
                    </View>
                </Modal>

                {this._renderAddFriendTile()}
            </ScrollView>
        )
    }
}

class FriendRow extends Component {
  constructor(props) {
      super(props);
      this.state = {
       isSelected:this.props.isSelected,
      }
  }

  componentDidMount(){
    console.log('didmount');
  }
    render(){
        var imageSource = (this.state.isSelected==true) ?  require('./images/tree.jpg') : ''
        console.log('friend'+!this.props.isSelected)
        return(
            <TouchableHighlight onPress={() => {this.props.pickContact(this.props.friend);this.setState({isSelected:!this.state.isSelected})}}>
                <View style={[styles.row, styles.friendRow]}>
                    <Image source={this.props.friend.image} style={styles.friendIcon}></Image>
                    <Text style={styles.name}>{this.props.friend.firstname} </Text>
                    <Text style={styles.name}>{this.props.friend.surname}</Text>

                    <View style={styles.roundIconContainer}>
                        <View style={styles.roundIcon}>
                            <View style={this.state.isSelected ? [styles.buttonActive, styles.buttonSmall]: [styles.modalButtonInactive, styles.buttonSmall]}>
                                <Image source={imageSource} style={styles.buttonTickSmall}></Image>
                            </View>
                        </View>
                    </View>
                </View>
            </TouchableHighlight>
        )
    }
}

关于javascript - React Native - 从数组中删除对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42182687/

相关文章:

javascript - 链接多个 Promise(处理回调)

javascript - 弹出窗口时焦点关闭按钮

android - React Native 中的 BackHandler 不工作

reactjs - React Native WebView 中的 incognito 和 cacheEnabled 属性有什么区别?

android - react native android moveTaskToBack?

javascript - Backbone 模型如何从 Ajax 结果触发事件?

javascript - Angularjs – 对主细节场景中未保存的更改发出警告

php - 当关联列等于 ____ 时循环显示多条记录

python - 使用类似枚举的函数迭代 numpy 数组

c - malloc 和 realloc 数组给出意外输出