Логический переключатель массива useState — Реагирует на родной

#reactjs #react-native

Вопрос:

Начинающий разработчик реагирует на родной язык.

я имею дело с проблемой шаблона проектирования , у меня есть несколько осязаемых возможностей в одном и том же компоненте (я должен сохранить это таким образом). для каждого из них у меня есть функция onPress, которая меняет фон и реверс . проблема в том, что функция зависит от текущего состояния, и когда я нажимаю на одну из них, каждый меняется .

 

function Grocery({ navigation }) {

  const [isPressed, setIsPressed] = useState(0);
  const onPress = () => setIsPressed(!isPressed);



  return (  
    
    <ScrollView>
      <Button title="home" onPress={() => {FindMatch(GetIngridients());navigation.navigate("MatchedRecipiesScreen");}}>press</Button>
    <View style={styles.container}>
      
    <TouchableOpacity style={styles.button} onPress={() => {AddToPanetry("pasta");onPress();}}  >
    <View style={isPressed amp;amp; styles.pressedButtonStyle} />
        <Image style={styles.imageright} source={require('../assets/Pastaa.jpg')} />
        <Text> pasta</Text>
      </TouchableOpacity>



      <TouchableOpacity onPress={() => {AddToPanetry("eggs");onPress();}}  >
      <View style={isPressed amp;amp; styles.pressedButtonStyle} />
        <Image style={styles.imageleft} source={require('../assets/eggs.jpg')} />
        <Text>eggs</Text>
      </TouchableOpacity>




      <TouchableOpacity onPress={() => {AddToPanetry("fish");onPress();}}  >
      <View style={isPressed amp;amp; styles.pressedButtonStyle} />
        <Image style={styles.imageleft} source={require('../assets/fish.jpg')} />
        <Text>fish</Text>
      </TouchableOpacity>


const styles = StyleSheet.create({
  container: {
    flexDirection: "row",
    flexWrap: "wrap",
    padding: 50,
    flexWrap: 'wrap',
    justifyContent: 'space-between',
  }
  ,
  imageleft: {
    borderRadius:100,
    borderWidth:2,
    borderColor:'black',
    height: 120,
    width: 150,
    borderRadius: 80,
    padding:25
  },
  button: {
    alignItems: "center",
   
  },
    tinyLogo: {
    width: 50,
    height: 50,
  },
  pressedButtonStyle: {
    position:"absolute",
    width:150,
    height:121,
    backgroundColor:'black',
    opacity:0.6,
    zIndex:100,
    borderRadius:80
  },
  imageright: {
    borderRadius:100,
    borderWidth:2,
    borderColor:'black',
    height: 120,
    width: 150,
    borderRadius: 80,
    padding:25
  }
});

 

Комментарии:

1. В вашем коде есть некоторые вещи, которые необходимо улучшить. Во-первых, не могли бы вы, пожалуйста, ввести код AddToPanetry функции? Вы также можете отредактировать вопрос и добавить его.

Ответ №1:

Один из подходов состоит в том, чтобы сохранить имена элементов в массиве или объекте, а затем проверить, был ли выбран конкретный элемент.

Вот еще один подход, который вы могли бы использовать:

 const HomeScreen = () => {
    const itemsData = [
        { name: 'Eggs', image: 'image require here', isSelected: false },
        { name: 'Pasta', image: '', isSelected: false },
        { name: 'Fish', image: '', isSelected: false },
    ];

    const [items, setItems] = useState(itemsData);

    const handleSelectItem = (selectedItemIndex) => {
        const itemsToSelect = items.map((item, index) => {
        if (selectedItemIndex === index) item.isSelected = !item.isSelected;
        return item;
        }, []);

        setItems(itemsToSelect);

        // your logic here
        // AddToPanetry(item[selectedItemIndex].name)
    };

    const renderItem = (item, index) => {
        const isSelected = items[index].isSelected;

        return (
        <TouchableOpacity
            style={[styles.button, isSelected amp;amp; styles.selectedButton]}
            onPress={() => handleSelectItem(index)}>
            {/* <Image source={item.image} /> */}
            <Text>{item.name}</Text>
        </TouchableOpacity>
        );
    };

    return (
        <View>
        <ScrollView>
            {itemsData.map((item, index) => renderItem(item, index))}
        </ScrollView>
        </View>
    );
};

const styles = StyleSheet.create({
  button: {
    backgroundColor: 'white',
    padding: 20,
  },
  selectedButton: {
    backgroundColor: 'pink',
  },
});
 

Комментарии:

1. Tnx ! есть идеи, почему я должен дважды щелкнуть по его работам?

Ответ №2:

Есть 2 варианта в зависимости от ваших потребностей.

  1. Вы можете хранить все свои данные и выбранное состояние в одном массиве с отслеживанием состояния. При нажатии вам нужно найти элемент в массиве, который должен обновиться.
     import * as React from 'react';
    import {
      Text,
      StyleSheet,
      TouchableOpacity,
      Button,
      FlatList,
      SafeAreaView,
    } from 'react-native';

    export default function Grocery({ navigation }) {
      const [state, setState] = React.useState([
        {
          label: 'pasta',
          pressed: false,
        },
        {
          label: 'eggs',
          pressed: false,
        },
        {
          label: 'fish',
          pressed: false,
        },
        {
          label: 'salad',
          pressed: false,
        },
      ]);

      const handlePress = (i) => {
        const newState = [...state];
        newState[i].pressed = !state[i].pressed;
        setState(newState);
      };

      return (
        <SafeAreaView style={{ flex: 1 }}>
          <FlatList
            data={state}
            ListHeaderComponent={() => (
              <Button
                title="home"
                onPress={() => {
                  console.log('press home');
                }}>
                press
              </Button>
            )}
            renderItem={({ item, index }) => (
              <TouchableOpacity
                key={index}
                id={index}
                onPress={() => handlePress(index)}
                style={[
                  styles.flatListTouchable,
                  item.pressed amp;amp; styles.flatListTouchablePressed,
                ]}>
                <Text style={styles.flatListTouchableText}>{item.label}</Text>
              </TouchableOpacity>
            )}
          />
        </SafeAreaView>
      );
    }

    const styles = StyleSheet.create({
      flatListTouchable: {
        width: '100%',
        backgroundColor: 'blue',
        color: 'white',
        padding: 30,
      },
      flatListTouchablePressed: {
        backgroundColor: 'black',
      },
      flatListTouchableText: {
        color: 'white'
      }
    });
 

Закуска


  1. Вы можете хранить свои данные и выбранное состояние отдельно. Выбранное состояние управляется в дочернем компоненте.
     import * as React from 'react';
    import {
      Text,
      StyleSheet,
      TouchableOpacity,
      Button,
      FlatList,
      SafeAreaView,
    } from 'react-native';

    const data = [
      {
        label: 'pasta',
      },
      {
        label: 'eggs',
      },
      {
        label: 'fish',
      },
      {
        label: 'salad',
      },
    ];

    export default function Grocery({ navigation }) {
      return (
        <SafeAreaView style={{ flex: 1 }}>
          <FlatList
            data={data}
            ListHeaderComponent={() => (
              <Button
                title="home"
                onPress={() => {
                  console.log('press home');
                }}>
                press
              </Button>
            )}
            renderItem={({ item, index }) => (
              <RenderItem item={item} index={index} />
            )}
          />
        </SafeAreaView>
      );
    }

    const RenderItem = ({ item, index }) => {
      const [pressed, setPressed] = React.useState(false);

      const handlePress = () => {
        setPressed(!pressed);
      };

      return (
        <TouchableOpacity
          key={index}
          id={index}
          onPress={handlePress}
          style={[
            styles.flatListTouchable,
            pressed amp;amp; styles.flatListTouchablePressed,
          ]}>
          <Text style={styles.flatListTouchableText}>{item.label}</Text>
        </TouchableOpacity>
      );
    };

    const styles = StyleSheet.create({
      flatListTouchable: {
        width: '100%',
        backgroundColor: 'blue',
        color: 'white',
        padding: 30,
      },
      flatListTouchablePressed: {
        backgroundColor: 'black',
      },
      flatListTouchableText: {
        color: 'white',
      },
    });
 

Закуска