Estoy tratando de lograr un solo elemento seleccionable simple, como se muestra en la imagen a continuación.
En este momento, he creado una matriz de mis elementos de datos y uso .map
para representar los componentes porque solo hay 3-4 elementos como máximo, ahora quiero seleccionar solo un elemento y cambiar el color sobre la base, y si seleccione cualquier otro elemento, debe anular la selección de todos los demás elementos, pero no del único elemento/componente seleccionado actualmente. Intenté hacer esto pero puedo seleccionarlos todos, obviamente. A continuación se muestra el código:
const items = [ { id: 1, iconName: 'male', title: 'Male', name: 'male', }, { id: 2, iconName: 'female', title: 'Female', name: 'female', }, { id: 3, iconName: 'transgender', title: 'Others', name: 'others', }, ]; const Component = ({dispatch, iconName, title, name}) => { const [isSelected, setIsSelected] = useState(false); return ( <TouchableOpacity activeOpacity={0.6} style={ isSelected ? [styles.selectable, {backgroundColor: 'green'}] : [styles.selectable, {backgroundColor: COLORS.PINK}] } onPress={() => { setIsSelected(!isSelected); }}> <View style={styles.row}> <Ionicon name={iconName} size={36} color="#fff" /> <Text>{title}</Text> </View> </TouchableOpacity> ); }; const Gender = () => { return ( <View> <View> <Text>Your Gender</Text> <View> {items.map(item => ( <Component key={item.id} title={item.title} iconName={item.iconName} /> ))} </View> </View> </View> ); };
Aunque podría resolver esto usando estados separados para cada botón, por lo que cada vez que se selecciona/presiona uno, los otros estados deberían volverse falsos. Pero luego tendría que representar el componente individual sin usar el método .map
que encuentro ineficiente. ¿Alguien puede proporcionar alguna solución basada en mi enfoque actual para este problema?
¡Gracias!
Considere mover isSelected al componente principal y, en lugar de almacenar un valor booleano, almacene la identificación del elemento seleccionado. Pase itemId, selectedId, setSelectedId (como una devolución de llamada) a los componentes secundarios y cambie la verificación de estilo a:
style={ itemId === selectedId ? [styles.selectable, {backgroundColor: 'green'}] : [styles.selectable, {backgroundColor: COLORS.PINK}] } onPress={() => { setSelectedId(itemId); }}>
Ahora puede deshacerse del seguimiento de si el elemento está seleccionado en el componente y solo preocuparse por él en el contexto del padre (como debería ser).
const Gender = () => { const [selectedId, setSelectedId] = useState(false); return ( <View> <View> <Text>Your Gender</Text> <View> {items.map(item => ( <Component key={item.id} itemId={item.id} selectedId={selectedId} setSelectedId={setSelectedId} title={item.title} iconName={item.iconName} /> ))} </View> </View> </View> ); };