React native - 动态添加onPress视图

时间:2017-02-06 22:37:28

标签: javascript ios listview reactjs react-native

我有一个包含按钮的视图 - onPress它会打开一个显示联系人列表的模式。

  1. onPress中的任何一个联系人(pickContact函数)我想动态地将新视图添加到_renderAddFriendTile(上面的按钮)。

  2. 理想情况下,每个联系人姓名(在模式中)旁边的“添加”图标都应该更新(“删除”图标),无论它们是否出现在_renderAddFriendTile视图中。

  3. 最好的方法是什么?

    [更新代码]

     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: 'name01',
                surname: 'surname01',
                image: require('../images/friends/avatar-friend-01.png')
            },
            {
                id: 2,
                firstname: 'name02',
                surname: 'surname02',
                image: require('../images/friends/avatar-friend-02.png')
            },
            {
                id: 3,
                firstname: 'name03',
                surname: 'surname03',
                image: require('../images/friends/avatar-friend-03.png')
            },
            {
                id: 4,
                firstname: 'name04',
                surname: 'surname04',
                image: require('../images/friends/avatar-friend-04.png')
            },
        ])
    
    
        class AppView extends Component {
            state = {
                isModalVisible: false,
                contactPicked: [],
                isFriendAdded: false,
            }
    
            setModalVisible = visible => {
                this.setState({isModalVisible: visible})
            }
    
            pickContact = (friend) => {
                if(this.state.contactPicked.indexOf(friend) < 0){
                    this.setState({
                        contactPicked: [ ...this.state.contactPicked, friend ],
    
                    })
                }
    
                if(this.state.contactPicked.indexOf(friend) >= 0){
                    this.setState({isFriendAdded: true})
                }
            }
    
            _renderAddFriendTile = () => {
                return(
                    <View style={{flex: 1}}>
                        <View style={[styles.step, styles.stepAddFriend]}>
                            <TouchableHighlight style={styles.addFriendButtonContainer} onPress={() => {this.setModalVisible(true)}}>
                                <View style={styles.addFriendButton}>
                                    <Text style={styles.addFriendButtonText}>Add a friend</Text>
                                </View>
                            </TouchableHighlight>
                        </View>
                    </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 style={{textAlign:'right'}}>Close</Text>
                                        </View>
                                    </TouchableHighlight>
                                    <ListView
                                        dataSource={friends}
                                        renderRow={(friend) => {
                                            return (
                                                <TouchableHighlight onPress={() => {this.pickContact()}}>
                                                    <View style={[styles.row, styles.friendRow]}>
                                                        <Image source={friend.image} style={styles.friendIcon}></Image>
                                                        <Text style={styles.name}>{friend.firstname} </Text>
                                                        <Text style={styles.name}>{friend.surname}</Text>
    
                                                        <View style={styles.pickContainer}>
                                                            <View style={styles.pickWrapper}>
                                                                <View style={this.state.isFriendAdded ? [styles.buttonActive,styles.buttonSmall]: [styles.buttonInactive,styles.buttonSmall]}>
                                                                    <Image source={this.state.isFriendAdded ? require('../images/button-active.png'): require('../images/button-inactive.png')} style={styles.buttonIcon}></Image>
                                                                </View>
                                                            </View>
                                                        </View>
                                                    </View>
                                                </TouchableHighlight>
                                            )
                                        }}
                                    />
                                </View>
                            </View>
                        </Modal>
    
                        {this._renderAddFriendTile()}
                    </ScrollView>
                )
            }
        }
    
        export default AppView
    

1 个答案:

答案 0 :(得分:5)

由于您需要动态更新内容,因此您需要利用本地状态对数据进行建模。 (另外你没有像Redux那样使用状态库管理)

state = {
    isModalVisible: false,
    contactPicked: null,
}

您的pickContact函数需要listView中的朋友数据,因此您需要使用所选行调用它:

 <TouchableHighlight onPress={() => {this.pickContact(friend)}}>

然后在pickContact功能中,使用新的contactsPicked数据模型更新您的用户界面

pickContact = (friend) => {
    this.setState({
      contactPicked: friend,
    });
}

这将使您的组件重新渲染,并且您可以在_renderAddFriendTile内放置一些逻辑以呈现一些额外的UI(视图,文本...),因为this.state.contactPicked上存在值您可以使用某些东西沿着这些方向:

_renderAddFriendTile = () => {
    return(
        <View style={{flex: 1}}>
            {this.state.contactPicked && (
              <View>
                <Text>{contactPicked.firstName}<Text>
              </View>
            )}
            <View style={[styles.step, styles.stepAddFriend]}>
                <TouchableHighlight style={styles.addFriendButtonContainer} onPress={() => {this.setModalVisible(true)}}>
                    <View style={styles.addFriendButton}>
                        <Text style={styles.addFriendButtonText}>Add a friend</Text>
                    </View>
                </TouchableHighlight>
            </View>
        </View>
    )
}

请注意,您现在保持状态为所选联系人的firstName,因此第2点应该很容易解决。在ListView的renderRow内,如果friend.firstname === this.state.contactPicked.firstname

,则呈现不同的图标

注意:不要依赖firstname进行此类检查,因为您可以重复检查,但这会失败。最佳解决方案是为您的列表模型提供每个联系人的唯一id属性,并使用该id属性检查上述逻辑。

附注

部分{this.state.contactPicked && (<View><Text>Some text</Text></View)}正在使用条件渲染。 &&充当 if ,因此如果this.state.contactPicked是真实的,它将呈现视图,否则它将不呈现任何内容(虚假和null值由作为&#34;无需渲染&#34;)。

当然,如果你想动态渲染多个项目,你的状态模型应该是一个数组,即contactsPicked,最初是空的。每次选择联系人时,您都会向阵列添加新的联系人对象。然后在_renderAddFriendTile内,您可以use map动态呈现多个组件。我认为您不会需要ListView,除非您想要一个单独的可滚动列表。

_renderAddFriendTile = () => {
    return(
        <View style={{flex: 1}}>
            {this.state.contactsPicked.length && (
              <View>
                {this.state.contactsPicked.map(contact => (
                  <Text>{contact.firstName}</Text>
                )}
              </View>
            )}
            <View style={[styles.step, styles.stepAddFriend]}>
                <TouchableHighlight style={styles.addFriendButtonContainer} onPress={() => {this.setModalVisible(true)}}>
                    <View style={styles.addFriendButton}>
                        <Text style={styles.addFriendButtonText}>Add a friend</Text>
                    </View>
                </TouchableHighlight>
            </View>
        </View>
    )
}