You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native替换已弃用ListItem及布局与功能优化问题

Hey there! I see you've migrated to Native Base after React Native's ListItem got deprecated, and you're dealing with two small issues—let's fix them up together.


Fixing the Right-Aligned Arrow in CardItem

The arrow isn't sticking to the far right because the default CardItem layout isn't leveraging flexbox correctly. We'll adjust the CardItem's style to split content into left/right sections, ensuring the arrow stays aligned to the right edge.

Creating Editable Label-Value List Items with Modal

We'll add state to track tenant info, modal visibility, and the current field being edited. Each list item will show a label and its corresponding value, and tapping it will open a modal to edit that value.

Here's your updated code with both fixes implemented:

import React, { Component } from 'react';
import { StyleSheet, View } from 'react-native';
import { 
  Container, Header, Content, Card, CardItem, Text, Icon, 
  Right, Left, Body, Title, Button, Modal, Input 
} from 'native-base';
import { Avatar } from 'react-native-elements';

class TenantDetails extends Component {
  state = {
    modalVisible: false,
    currentEditingField: '',
    tenantInfo: {
      firstName: 'John',
      lastName: 'Test',
      email: 'joinh@gmail.com',
      phone: 'xxx-xxx-xxxx'
    }
  };

  openEditModal = (field) => {
    this.setState({
      modalVisible: true,
      currentEditingField: field
    });
  };

  closeEditModal = () => {
    this.setState({ modalVisible: false });
  };

  saveEditedValue = () => {
    // Add your save logic here (e.g., API call, state persistence)
    this.closeEditModal();
  };

  render() {
    const { navigation } = this.props;
    const { tenantInfo, modalVisible, currentEditingField } = this.state;
    // Format field name for modal title (e.g., "firstName" → "First Name")
    const formattedFieldName = currentEditingField
      .replace(/([A-Z])/g, ' $1')
      .replace(/^./, str => str.toUpperCase());

    return (
      <Container>
        <Header>
          <Left>
            <Button transparent onPress={() => navigation.goBack()}>
              <Icon name='arrow-back' />
            </Button>
          </Left>
          <Body>
            <Title>My Profile</Title>
          </Body>
          <Right />
        </Header>
        <Content>
          <View style={styles.userRow}>
            <View style={styles.userImage}>
              <Avatar
                rounded
                size="large"
                source={{ uri: 'https://myirent.com/rent/appImg/person-icon.png', }}
              />
            </View>
            <View>
              <Text style={{ fontSize: 16 }}>{`${tenantInfo.firstName} ${tenantInfo.lastName}`}</Text>
              <Text style={{ color: 'gray', fontSize: 16, }} > {tenantInfo.email}{'\n'}{tenantInfo.phone} </Text>
            </View>
          </View>
          <Card>
            <View style={styles.containerTextHeader}>
              <Text style={styles.infoTextHeader}>Tenant Details</Text>
            </View>
            {/* First Name Item */}
            <CardItem 
              style={styles.listItem}
              onPress={() => this.openEditModal('firstName')}
            >
              <View style={styles.labelSection}>
                <Icon active name="person" style={styles.itemIcon} />
                <Text style={styles.labelText}>First Name</Text>
              </View>
              <View style={styles.valueSection}>
                <Text style={styles.valueText}>{tenantInfo.firstName}</Text>
                <Icon name="arrow-forward" style={styles.rightArrow} />
              </View>
            </CardItem>
            {/* Last Name Item */}
            <CardItem 
              style={styles.listItem}
              onPress={() => this.openEditModal('lastName')}
            >
              <View style={styles.labelSection}>
                <Icon active name="person" style={styles.itemIcon} />
                <Text style={styles.labelText}>Last Name</Text>
              </View>
              <View style={styles.valueSection}>
                <Text style={styles.valueText}>{tenantInfo.lastName}</Text>
                <Icon name="arrow-forward" style={styles.rightArrow} />
              </View>
            </CardItem>
            {/* Email Item */}
            <CardItem 
              style={styles.listItem}
              onPress={() => this.openEditModal('email')}
            >
              <View style={styles.labelSection}>
                <Icon active name="mail" style={styles.itemIcon} />
                <Text style={styles.labelText}>Email</Text>
              </View>
              <View style={styles.valueSection}>
                <Text style={styles.valueText}>{tenantInfo.email}</Text>
                <Icon name="arrow-forward" style={styles.rightArrow} />
              </View>
            </CardItem>
            {/* Phone Item */}
            <CardItem 
              style={styles.listItem}
              onPress={() => this.openEditModal('phone')}
            >
              <View style={styles.labelSection}>
                <Icon active name="call" style={styles.itemIcon} />
                <Text style={styles.labelText}>Phone</Text>
              </View>
              <View style={styles.valueSection}>
                <Text style={styles.valueText}>{tenantInfo.phone}</Text>
                <Icon name="arrow-forward" style={styles.rightArrow} />
              </View>
            </CardItem>
          </Card>

          {/* Edit Modal */}
          <Modal 
            isVisible={modalVisible} 
            onBackdropPress={this.closeEditModal}
            style={styles.modal}
          >
            <View style={styles.modalContent}>
              <Text style={styles.modalTitle}>Edit {formattedFieldName}</Text>
              <Input
                value={tenantInfo[currentEditingField]}
                onChangeText={(text) => this.setState(prevState => ({
                  tenantInfo: {
                    ...prevState.tenantInfo,
                    [currentEditingField]: text
                  }
                }))}
                style={styles.modalInput}
                autoFocus
              />
              <View style={styles.modalButtonRow}>
                <Button 
                  light 
                  style={styles.modalButton}
                  onPress={this.closeEditModal}
                >
                  <Text>Cancel</Text>
                </Button>
                <Button 
                  primary 
                  style={styles.modalButton}
                  onPress={this.saveEditedValue}
                >
                  <Text>Save</Text>
                </Button>
              </View>
            </View>
          </Modal>
        </Content>
      </Container>
    );
  }
}

const styles = StyleSheet.create({
  userRow: { alignItems: 'center', flexDirection: 'row', paddingVertical: 6, paddingHorizontal: 15, },
  userImage: { marginRight: 12, },
  containerTextHeader: { paddingVertical: 12, backgroundColor: '#F4F5F4', },
  infoTextHeader: { fontSize: 16, marginLeft: 20, color: 'gray', fontWeight: '500', },
  // List Item Styles
  listItem: { 
    flexDirection: 'row', 
    justifyContent: 'space-between', 
    alignItems: 'center',
    paddingVertical: 8
  },
  labelSection: { flexDirection: 'row', alignItems: 'center', },
  itemIcon: { marginRight: 10, color: '#666' },
  labelText: { fontSize: 15, color: '#333' },
  valueSection: { flexDirection: 'row', alignItems: 'center', },
  valueText: { fontSize: 15, color: '#666', marginRight: 8 },
  rightArrow: { color: '#999' },
  // Modal Styles
  modal: { justifyContent: 'center', alignItems: 'center' },
  modalContent: { 
    width: '90%', 
    backgroundColor: 'white', 
    borderRadius: 8, 
    padding: 20 
  },
  modalTitle: { fontSize: 18, fontWeight: '500', marginBottom: 15 },
  modalInput: { marginBottom: 20 },
  modalButtonRow: { flexDirection: 'row', justifyContent: 'flex-end', gap: 10 },
  modalButton: { borderRadius: 4 }
});

export default TenantDetails;

Key Changes Explained:

  1. Arrow Alignment:

    • Added justifyContent: 'space-between' to listItem style, which pushes the label section left and value/arrow section right.
    • Wrapped icon+label and value+arrow in separate views for clean layout.
  2. Editable Label-Value Items:

    • Added state to track tenant info, modal visibility, and the current field being edited.
    • Added onPress handlers to each CardItem to trigger the modal.
    • Implemented a Native Base Modal with an input field to edit the selected value, plus save/cancel buttons.
    • Dynamic modal title that formats the field name for readability.

内容的提问来源于stack exchange,提问作者myTest532 myTest532

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:57:08