开发者问题收集

未定义不是一个函数(靠近'... map ...')

2021-01-09
1510

当我点击 JSX 中的 Pressable 元素时,我收到错误:Undefined 不是函数(靠近“... wines.map ...”)。日志显示它来自 JSX 中的 wines.map 循环。我不确定我尝试更改 toggle 函数中的数据的方式或我设置默认 useState 数组对象的方式可能存在什么问题。代码应该为每个按钮独立切换两种不同类型的图像。

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */
import 'react-native-gesture-handler';
import React, {useState} from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import {
  SafeAreaView,
  StyleSheet,
  ScrollView,
  View,
  Text,
  StatusBar,
  ImageBackground,
  Image,
  TextInput,
  Button,
  TouchableNativeFeedback,
  TouchableWithoutFeedback,
  TouchableOpacity,
  TouchableHighlight,
  FlatList,
  Pressable,
  RecyclerViewBackedScrollViewComponent
} from 'react-native';

import { Immersive } from 'react-native-immersive';


const fullWine = require('../images/selected-wine.png');
const emptyWine = require('../images/empty-wine-icon.png');



const WineList = () => {


    Immersive.on()
    Immersive.setImmersive(true)



    const [wines, setWines] = useState([
 
        {
            name: "2018 Prezzo",
            info: "What dsbetter way to spend a lazy afternoon than sipping away on this wine.",
            imageUrl: emptyWine

        },
        {
            name: "2018 Coqueta",
            info: "A litstle flirty wine.",
            imageUrl: emptyWine
        }
       
    ])
  
    function toggle(pressedWine){

        let oldWines = [...wines]

        
        let newWines = oldWines.map((wine) => {
            
            if(wine === pressedWine){
                if(wine.imageUrl == emptyWine){
                    wine.imageUrl = fullWine;
                } else {
                    wine.imageUrl = emptyWine;
                }
            }
            return wine;
        });
       
        setWines({newWines});

        // setWines({newWines});
    }
   

    return (
    <View style={{flex:1}}>  
        <ScrollView style={styles.scrollView}>
            <View style={styles.headerMessage}>
                <Text style={styles.headerMessageText}>Select your wines for tasting</Text>
            </View>

            <View style={[styles.wineListWrapper]}>

                { wines.map((wine, index) => {
                    return(
                    <View key={index} style={[styles.item]}>
                        <Image source={require('../images/Peresozo2018.png')} style={[styles.bottle]} />

                        <View style={[styles.infoWrapper]}>
                        
                    
                            <Text style={[styles.itemTitle]}>{wine.name}</Text>
                            <Text style={[styles.itemInfo]}> 
                            
                                {wine.info}
                            
                            </Text>
                        </View>

                        <Pressable onPress={ (wine) => toggle(wine) }  style={[styles.wineIcon]}>
                            <Image source={wine.imageUrl}  />
                        </Pressable>


                    </View>
                    )
                
                })}

                 
            </View>
        </ScrollView>
        
        <TouchableOpacity  onPress={() => alert('yo') }  style={[styles.footerButton]}>
            <Text style={[styles.footerText]}>Start Tasting</Text>
        </TouchableOpacity>
    </View>    
        
    )
}

const styles = StyleSheet.create({
    footerButton:{
        flex:1,
        justifyContent: 'flex-end',
        alignContent:'center',
        alignItems:'center',
        backgroundColor:'white',
        paddingTop:90
    
    },
    footerText:{
        fontFamily: 'Charm-Regular',
        fontSize:40,
        color:'#624124'
        
        
    },
    item:{
        flex:1,
        flexDirection: 'row',
        justifyContent: 'space-between',
        padding: 10
    },
    infoWrapper:{
        flex:0.7, 
        flexWrap: 'wrap', 
        flexDirection: 'row', 
        padding:10, 
        alignSelf:'flex-start',
        justifyContent: 'space-between',
        marginTop: -30,
        marginLeft:1
    },
    itemTitle:{
        color:'white',
        fontFamily: 'Charm-Regular',
        fontSize: 40,
        
    },
    itemInfo:{
        color:'white',
        fontSize: 20,
        
    },
    wineIcon:{
        padding:5,
        flex:0.15
    },
    wineListWrapper:{
        marginLeft: 10,
        marginTop: 40
    },
    bottle:{
        marginLeft: 2,
        width: 80,
        height: 250,
        resizeMode: 'contain',
       
        
    },
    scrollView:{
        backgroundColor: '#4B4239',
    },
    headerMessage:{
        backgroundColor: 'white',
        flex: 1,
        alignItems: 'center',
        alignContent: 'center',
        justifyContent: 'center',
        flexDirection: 'column',
        alignSelf: 'center',
        width:400,
        borderRadius: 4,
        padding: 0,
        marginTop: 10


    },
    headerMessageText:{
        color: '#4B4239',
        textAlign: 'center',
        fontSize: 30,
        fontFamily: 'Charm-Regular',
        lineHeight: 50
    }

})

export default WineList
1个回答

问题是,您在更新对象时将其设置为 wines 状态:

setWines({ newWines });

由于状态的值是一个数组,您可能指的是:

setWines(newWines);

此外,传递给 onPress 回调的参数不是 wine 对象,而是 PressEvent 。因此,您正在使用来自回调参数的事件对象 隐藏 .map() 中的 wine 变量。

您可能想将 wine 从循环中传递给 toggle ,因此只需删除 (wine) => 参数即可。

<Pressable onPress={() => toggle(wine)} style={[styles.wineIcon]}>
  <Image source={wine.imageUrl} />
</Pressable>
cbr
2021-01-09