【问题标题】:React Native: FlatList Opens Modal for all Items Instead of Selected ItemReact Native:FlatList为所有项目而不是选定项目打开模式
【发布时间】:2020-12-10 12:27:20
【问题描述】:

我正在使用React Native FlatListReact Native Modal

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

但是,如果 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>

                </>
            );
    };

【问题讨论】:

    标签: javascript react-native react-native-flatlist react-native-modal


    【解决方案1】:

    问题是你在renderItem方法中渲染了modal,所以每次选择一个item时,modal会在每个渲染的item中打开。

    为了解决这个问题,您必须在 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 状态,所以如果它不为空,那么模态将可见

    【讨论】:

    • Monlina 谢谢你的建议。你碰巧有什么例子吗?总的来说,我对 Modal 和 React Native 还很陌生。
    • 我已经更新了答案。我没有尝试过代码,我很快就完成了,但类似。
    猜你喜欢
    • 1970-01-01
    • 2023-03-12
    • 2020-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-09
    • 2022-11-27
    • 1970-01-01
    相关资源
    最近更新 更多