#javascript #react-native #react-native-flatlist #react-native-modal
#javascript #react-native #react-native-flatlist #react-native-modal
Вопрос:
Я использую React Native FlatList и React Native Modal.
При нажатии на элемент из FlatList я хочу просмотреть только 1 модальный (содержащий сведения о выбранном элементе).
Однако, если в FlatList есть 4 элемента, выбор 1 элемента приводит к появлению всех 4 модалов.
Могу ли я в любом случае отобразить только 1 модальный для 1 выбранного элемента в FlatList вместо нескольких модальных?
Фрагмент кода ниже (некоторые строки кода были удалены за ненадобностью):
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>
</>
);
};
Ответ №1:
Проблема в том, что вы визуализируете модал в методе renderItem, поэтому каждый раз, когда вы выбираете элемент, модал будет открываться в каждом визуализированном элементе.
Чтобы решить эту проблему, вам нужно будет отобразить пользовательский модальный компонент с абсолютной позицией на том же уровне вашего FlatList и передать информацию о выбранном элементе в качестве реквизита.
Обновить
Просто что-то вроде этого:
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, поэтому, если оно не равно null, модальное значение будет видно
Комментарии:
1. Monlina Спасибо за предложение. У вас случайно нет каких-либо примеров? Я довольно новичок в модальном и React Native в целом.
2. Я обновил ответ. Я не пробовал код, и я сделал это быстро, но что-то похожее.