#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 варианта в зависимости от ваших потребностей.
- Вы можете хранить все свои данные и выбранное состояние в одном массиве с отслеживанием состояния. При нажатии вам нужно найти элемент в массиве, который должен обновиться.
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'
}
});
- Вы можете хранить свои данные и выбранное состояние отдельно. Выбранное состояние управляется в дочернем компоненте.
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',
},
});