javascript - React native——动态添加onPress View

标签 javascript ios listview reactjs react-native

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

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

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

最好的方法是什么?

[更新代码]

 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

最佳答案

由于您需要动态更新某些内容,这清楚地表明您需要使用本地状态来为该数据建模。 (撇开你没有使用像 Redux 这样的状态库管理)

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

你的 pickContact函数需要 listView 中的好友数据,所以你需要在选中的行中调用它:

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

然后在你的pickContact里面功能,使用新的 contactsPicked 更新您的 UI数据模型

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

这将使您的组件重新渲染,您可以在 _renderAddFriendTile 中放置一些逻辑鉴于 this.state.contactPicked 上存在值(value),呈现一些额外的 UI( View 、文本..)您可以按照以下方式使用:

_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 点应该很容易找到。就在里面renderRow的 ListView,呈现不同的图标,如果 friend.firstname === this.state.contactPicked.firstname

注意:不要依赖名字来进行此类检查,因为您可能会重复检查,这样会失败。最好的解决方案是为您的列表模型提供一个独特的 id每个联系人的属性(property)并使用它id用于检查上述逻辑的属性。

边注

部分{this.state.contactPicked && (<View><Text>Some text</Text></View)}正在使用条件渲染。 &&充当 if 所以如果 this.state.contactPicked是真实的,它将渲染 View ,否则它将不渲染任何东西(falsy 和 null 值被 react 解释为“没有渲染”)。

当然,如果您想动态呈现多个项目,您的状态模型应该是一个数组,即 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>
    )
}

关于javascript - React native——动态添加onPress View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42078532/

相关文章:

javascript - 在 Android 中通过 Javascript 隐藏/显示 WebView

ios - 尝试将文本附加到 Swift 循环内的属性

ios - 在ios sdk中获取当月星期一的所有日期

java - ANDROID:在另一个 Activity 中保存逐项 ListView 的用户数据

java - 实例化后,列表可以以某种方式分配给另一个类的列表吗?

javascript - 扩展函数

javascript-objects - 如何将对象字面量转换为函数

javascript - ReactJS - Handsontable - 确定更改

ios - 子类化/扩展 UIView,以便所有其他 View (UIImageView、UITextField ...)在创建时继承

android - OnClick 事件重复 ListView 项目