使用 UseState 更新对象数组项

时间:2021-01-08 00:46:21

标签: javascript reactjs react-native

我正在尝试为传递给 useState 的对象数组中的每个项目切换图像源 onPress。我的 toggle 函数应该创建 wines 对象的副本并仅更改单击按钮的 img url。当我点击 Pressable 元素时,什么也没有发生。


/**
 * 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';

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

const wineImg = [emptyWine, fullWine];

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(){
        let newArray = [...wines]
        if(newArray.imageUrl == emptyWine){

            newArray.imageUrl = fullWine
            setWines(newArray)
        } else {
            newArray.imageUrl = emptyWine
            setWines(newArray)
        }
    }
   

    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={toggle}  style={[styles.wineIcon]}>
                            <Image source={wine.imageUrl}  />
                        </Pressable>


                    </View>
                    )
                
                })}

               
            </View>
        </ScrollView>
        

    </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 个答案:

答案 0 :(得分:1)

toggle 有很多错误:newArray.imageUrl 将返回 undefined 因为您需要引用特定元素,例如 newArray[0].imageUrl。 总的来说,我会做这样的事情,让它发挥作用:

1)更改切换功能

 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 });
 }

2) 更改可按下:

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

请进行测试,并提供反馈,以便我在出现问题时进行更正。