React native - 动态添加onPress视图

Joh*_*ohn 5 javascript listview ios reactjs react-native

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

  1. 任何这些联系人的onPress(pickContact函数)我想动态地添加一个新的View到_renderAddFriendTile(上面的按钮).

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

最好的方法是什么?

[更新代码]

 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
Run Code Online (Sandbox Code Playgroud)

rgo*_*ezz 5

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

state = {
    isModalVisible: false,
    contactPicked: null,
}
Run Code Online (Sandbox Code Playgroud)

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

 <TouchableHighlight onPress={() => {this.pickContact(friend)}}>
Run Code Online (Sandbox Code Playgroud)

然后在您的pickContact函数内部,使用新contactsPicked数据模型更新UI

pickContact = (friend) => {
    this.setState({
      contactPicked: friend,
    });
}
Run Code Online (Sandbox Code Playgroud)

这将使您的组件重新渲染,并且您可以在内部放置一些逻辑_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>
    )
}
Run Code Online (Sandbox Code Playgroud)

请注意,您现在保持状态为所选联系人的firstName,因此第2点应该易于解决.在renderRowListView 内部,渲染一个不同的Icon iffriend.firstname === this.state.contactPicked.firstname

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

附注

该部分{this.state.contactPicked && (<View><Text>Some text</Text></View)}使用条件渲染.&&作为if if的行为如果this.state.contactPicked是真实的,它将呈现视图,否则它将不呈现任何内容(falsy和null值被反应解释为"无需呈现").

当然,如果要动态渲染多个项目,则状态模型应该是一个数组,即contactsPicked最初为空.每次选择联系人时,都会向阵列添加新的联系人对象.然后在里面_renderAddFriendTile你可以使用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>
    )
}
Run Code Online (Sandbox Code Playgroud)