2

我正在使用React Native FlatListReact Native Modal

单击 FlatList 中的项目后,我只想查看 1 个模态(包含所选项目的详细信息)。

但是,如果 FlatList 中有 4 个项目,则选择 1 个项目会导致所有 4 个模态框都弹出。

无论如何我只能为 FlatList 中的 1 个选定项目显示 1 个模态而不是多个模态?

下面的代码片段(一些代码行被删除,因为它不需要):

    constructor(props) {
            super(props);
            this.state = {
                dataSource: [],
                isLoading: true,
                modalVisible: false,
            }
        }
    
    setModalVisible = (visible) => {
            this.setState({ modalVisible: visible });
        } 
        
    
        viewModal(item, price) {
            const { modalVisible } = this.state;
            return (
                <Modal
                    statusBarTranslucent={true}
                    animationType={"slide"}
                    transparent={true}
                    visible={modalVisible}
                    onRequestClose={() => {
                        Alert.alert("Modal has been closed.");
                    }}
                >
                    <View>
                        <View>
                            <View>
                                <Text>
                                    Appointment Start Time:
                                </Text>
                                <Text>
                                    {moment(item.time_start).format('h:mm a')}
                                </Text>
                            </View>
    
                            <View>
                                <Text>
                                    Appointment End Time:
                                </Text>
                                <Text>
                                    {moment(item.end_start).format('h:mm a')}
                                </Text>
                            </View>
    
                            
    
                            
                            <View style={styles.row}>
                                <Text>
                                    Total:
                                </Text>
                                <Text>
                                    {price}
                                </Text>
                            </View>
                            
                            <View>
                                <View>
                                    <Button
                                        mode="outlined"
                                        onPress={() => {
                                            this.setModalVisible(!modalVisible);
                                        }}
                                    >
                                        {'Cancel'}
                                    </Button>
                                </View>
                                
                                <View>
                                    <Button
                                        mode="contained"
                                        onPress={() => {
                                            this.setModalVisible(!modalVisible);
                                        }}
                                    >
                                        {'Accept'}
                                    </Button>
                                </View>
                            </View>
                        </View>
                    </View>
                </Modal>
            );
        }
    
        viewFreelancerTime() {
            return (
                <View>
                    <FlatList
                        renderItem={({ item }) => {
                            let totalPrice = (parseFloat(item.service_price) + parseFloat(item.service_deposit)).toFixed(2);
                            return (
                                <Container>
                                    {this.viewModal(item, totalPrice)}
                                    <TouchableNativeFeedback
                                        onPress={() => {
                                            this.setModalVisible(true);
                                        }}
                                    >
                                        <View>
                                            <View>
                                                <Text>
                                                    {moment(item.time_start).format('h:mm a')}
                                                </Text>
                                            </View>
    
                                            <View>
                                                <Text>
                                                    {totalPrice}
                                                </Text>
                                            </View>
                                        </View>
                                    </TouchableNativeFeedback>
                                </Container>
                            );
                        }}
                    />
                </View>
            );
        }

render() {
            return (
                <>
                    <View style={{ flex: 1 }}>
                        {this.viewFreelancerTime()}
                    </View>

                </>
            );
    };
4

1 回答 1

1

问题是您在 renderItem 方法中渲染模态,所以每次选择一个项目时,模态都会在每个渲染的项目中打开。

为了解决这个问题,您必须在 FlatList 的同一级别渲染一个具有绝对位置的自定义 Modal 组件,并将所选项目信息作为道具传递。

更新

就像这样:

import React, {useState} from "react";
import { Modal } from "react-native";

export default function MyFlatList(props) {
  const [selectedItem, setSelectedItem] = useState(null);

  const handleOnSelectItem = (item) => {
    setSelectedItem(item);
  };

  const handleOnCloseModal = () => {
    setSelectedItem(null);
  };

  renderItem = ({ item }) => {
    return (
      <Container>
        <TouchableNativeFeedback onPress={() => handleOnSelectItem(item)}>
          <View>
            <View>
              <Text>{moment(item.time_start).format("h:mm a")}</Text>
            </View>

            <View>
              <Text>{totalPrice}</Text>
            </View>
          </View>
        </TouchableNativeFeedback>
      </Container>
    );
  };

  return (
    <View>
      <FlatList renderItem={this.renderItem} />
      <CustomModal isVisible={selectedItem} selectedItem={selectedItem} onClose={handleOnCloseModal} />
    </View>
  );
}

export function CustomModal(props) {
  const { isVisible, item, onClose,  /*...*/ } = props;

  // Play with the item data
  let totalPrice = (
    parseFloat(item.servicePrice) + parseFloat(item.serviceDeposit)
  ).toFixed(2);

  return <Modal visible={isVisible} onRequestClose={onClose}>{/*...*/}</Modal>; // Render things inside the data
}

如果您要实现无限滚动,我建议您进行分页并使用 FlatList 原生道具。

Pd:为了减少由于状态更新而重新渲染,我正在重用 selectedItem 状态,所以如果它不为空,那么模态将可见

于 2020-08-21T06:17:17.757 回答