Używam React Native Expo dla następującego projektu w zasadzie chcę pobrać wybrany element z płaskiej listy i wyświetlić go w trybie modalnym

import React,{ Component}from 'react';
import {View,Text,Image,StyleSheet,Modal,Button} from 'react-native';
import { FlatList, TouchableOpacity, ScrollView } from 'react-native-gesture-handler';
import Card from '../shared/card';
import { AppLoading } from 'expo';
import * as Font from 'expo-font';



export default class MealSearch extends Component{

    constructor(props){
        super(props)

        this.state = {
            loaded:false,
            show:false,
            key:''

        }}

    render(){
       const meal= [ {title:'My hero Academia',img:{uri:'https://i.cdn.turner.com/adultswim/big/img/2018/05/10/MHA_Header.png'}, body:'Rating : 4.5/5' , id :'1'},
        {title:'Naruto',img:{uri:'https://store-images.s-microsoft.com/image/apps.15041.71343510227343465.377174a9-abc8-4da3-aaa6-8874fdb9e2f5.00fc0a9e-295e-40ca-a391-58ed9f83e9a0?mode=scale&q=90&h=1080&w=1920&background=%23FFFFFF'}, body:'Rating : 5/5' , id :'2'},
        {title:'Attack On Titan',img:{uri:'https://www.denofgeek.com/wp-content/uploads/2013/12/attack-on-titan-main.jpg?fit=640%2C380'}, body:'Rating : 4.5/5' , id :'3'},
        {title:'Fate: Unlimited Blade Works',img:{uri:'https://derf9v1xhwwx1.cloudfront.net/image/upload/c_fill,q_60,h_750,w_1920/oth/FunimationStoreFront/2066564/Japanese/2066564_Japanese_ShowDetailHeaderDesktop_496a6d81-27db-e911-82a8-dd291e252010.jpg'}, body:'Rating : 4.5/5' , id :'4'}
    ]


        const handlePress = (meal_data) =>{
            this.setState({show: true});
            this.setState({selectedMeal:meal_data});
            console.log(meal_data)
        }


        return(
            <View style={styles.view} >
            <FlatList
                keyExtractor={item => item.id}
                data={meal}
                renderItem={({item})=>(
                    <Card>
                        <TouchableOpacity onPress={(_item)=>{handlePress(item)}}>                           
                            <View style={styles.mealItem}>                 
                                <Image style={{width:300,height:150}} resizeMode={'contain'} source={item.img} marginLeft={30}/>
                                <View style={styles.descrip}>
                                    <Text style={styles.rating}>{item.title}</Text>
                                    <Text style={styles.name}>{item.body}</Text>
                                </View>
                            </View>
                        </TouchableOpacity>                        
                    </Card>


                )}
            />

            <Modal
                transparent={true}
                visible={this.state.show}   
               >
                <View style={styles.modal}>
                    <View style={styles.inModal}> 


                    <Button title='End' onPress={()=>{this.setState({show:false})}}/>
                    </View> 
                </View>

            </Modal>    
            </View>
        );}

}


To jest kod, nad którym obecnie pracuję. Chcę, aby „meal_data” w „handlePress” było wyświetlane wewnątrz mojego modalnego „meal_data” to wybrany element z płaskiej listy.

              <Modal
                transparent={true}
                visible={this.state.show}   
               >
                <View style={styles.modal}>
                    <View style={styles.inModal}> 
                    <Button title='End' onPress={()=>{this.setState({show:false})}}/>
                    </View> 
                </View>

            </Modal>

Chcę go wyświetlić tutaj nad przyciskiem

-1
Pabasara Ratnayake 20 marzec 2020, 09:47

2 odpowiedzi

Najlepsza odpowiedź

Zmień te wiersze kodu:

  • Zmień: <TouchableOpacity onPress={(_item)=>{handlePress(item)}}> Do <TouchableOpacity onPress={() => this.handlePress(item)}>

  • Usuń ten kod wewnątrz render ():

const handlePress = (meal_data) =>{
  this.setState({show: true});
  this.setState({selectedMeal:meal_data});
  console.log(meal_data)
}
  • Zamiast tego umieść ten kod powyżej metody render ():
handlePress = (meal_data) =>{
  this.setState({show: true, selectedMeal: meal_data});
  console.log(meal_data)
}
  • Stan wewnętrzny
this.state = {
  loaded:false,
  show:false,
  key:''
  selectedMeal: null // Add this property
}}

Po tym będziesz mieć dostęp do selectedMeal w swoim modalu.

  • Umieść ten kod wewnątrz modalu (lub gdzieś indziej)
{this.state.selectedMeal && (
  <View>
    <Text>{this.state.selectedMeal.title}</Text>
  </View>
)}
0
NYSamnang 20 marzec 2020, 09:22

Najpierw zadeklaruj swoje handlePress poza metodą renderowania. Inną rzeczą jest to, że this.setState() jest asynchroniczne, więc najpierw ustaw dane, a następnie pokaż modalne. Twój ostateczny kod powinien wyglądać następująco:

import React, { Component } from 'react';
import { View, Text, Image, StyleSheet, Modal, Button } from 'react-native';
import { FlatList, TouchableOpacity, ScrollView } from 'react-native-gesture-handler';
import Card from '../shared/card';
import { AppLoading } from 'expo';
import * as Font from 'expo-font';

export default class MealSearch extends Component {
  constructor(props) {
    super(props)

    this.state = {
      loaded: false,
      show: false,
      key: ''
    }
  }

  handlePress = (meal_data) => {
    this.setState({ selectedMeal: meal_data }, () => {
      this.setState({ show: true });
    });
    console.log(meal_data)
  }

  render() {
    const meal = [
      { title: 'My hero Academia', img: { uri: 'https://i.cdn.turner.com/adultswim/big/img/2018/05/10/MHA_Header.png' }, body: 'Rating : 4.5/5', id: '1' },
      { title: 'Naruto', img: { uri: 'https://store-images.s-microsoft.com/image/apps.15041.71343510227343465.377174a9-abc8-4da3-aaa6-8874fdb9e2f5.00fc0a9e-295e-40ca-a391-58ed9f83e9a0?mode=scale&q=90&h=1080&w=1920&background=%23FFFFFF' }, body: 'Rating : 5/5', id: '2' },
      { title: 'Attack On Titan', img: { uri: 'https://www.denofgeek.com/wp-content/uploads/2013/12/attack-on-titan-main.jpg?fit=640%2C380' }, body: 'Rating : 4.5/5', id: '3' },
      { title: 'Fate: Unlimited Blade Works', img: { uri: 'https://derf9v1xhwwx1.cloudfront.net/image/upload/c_fill,q_60,h_750,w_1920/oth/FunimationStoreFront/2066564/Japanese/2066564_Japanese_ShowDetailHeaderDesktop_496a6d81-27db-e911-82a8-dd291e252010.jpg' }, body: 'Rating : 4.5/5', id: '4' }
    ]

    return (
      <View style={styles.view} >
        <FlatList
          keyExtractor={item => item.id}
          data={meal}
          renderItem={({ item }) => (
            <Card>
              <TouchableOpacity onPress={() => { this.handlePress(item) }}>
                <View style={styles.mealItem}>
                  <Image style={{ width: 300, height: 150 }} resizeMode={'contain'} source={item.img} marginLeft={30} />
                  <View style={styles.descrip}>
                    <Text style={styles.rating}>{item.title}</Text>
                    <Text style={styles.name}>{item.body}</Text>
                  </View>
                </View>
              </TouchableOpacity>
            </Card>


          )}
        />

        <Modal
          transparent={true}
          visible={this.state.show}
        >
          <View style={styles.modal}>
            <View style={styles.inModal}>


              <Button title='End' onPress={() => { this.setState({ show: false }) }} />
            </View>
          </View>

        </Modal>
      </View>
    );
  }
}

0
Kishan Bharda 20 marzec 2020, 08:27