Puedo tener una matriz como esta
const dayOfWeek = ["Sun", "Mon", "Tus", "Wed", "Thu", "Fri", "Sat"]Y tengo un componente de chip como este
const DateItem = (props: DateItemProps) => { const { days, selected, setSelected } = props return ( <TouchableOpacity row center onPress={() => { setSelected(!selected) }} style={!selected ? CONTAINER_WITHOUT_SELECTED : CONTAINER_WITH_SELECTED} > <Text style={!selected ? TEXT_WITHOUT_SELECTED : TEXT_WITH_SELECTED}>{days}</Text> {selected && <Icon name="check" color="white" />} </TouchableOpacity> ) } export default DateItemUso el gancho useState para verificar si se seleccionó el elemento
const [selected, setSelected] = useState(false)Y usa este gancho así
<View row style={{ flexWrap: "wrap" }}> {dayOfWeek.map((item, index) => ( <View> {console.log("index ", selected[index])} <DateItem days={item} selected={selected} setSelected={setSelected} /> </View> ))} </View>El problema es que cada vez que hago clic en un elemento, todos los elementos se verifican al mismo tiempo, entonces, ¿cómo puedo hacer clic en un elemento y luego en todos los demás elementos sin hacer clic? gracias
Aquí es cuando hago clic en un elemento
Puedes hacerlo:
const [selected, setSelected] = useState()Y en la función de mapa:
<DateItem days={item} selected={selected === item} setSelected={setSelected} />Y en setSelected:
// instead of !selected setSelected(item)Si, en cambio, desea seleccionar varios elementos, use una matriz de días seleccionados en estado de uso:
const [selected, setSelected] = useState([])Y en la función de mapa:
<DateItem days={item} selected={selected.indexOf(item) !== -1} setSelected={setSelected} />Y en setSelected:
setSelected((previous) => { const temp = previous; // either add or remove the new item from temp with temp.push() and temp.slice() return temp; })Creo que se debe a que el tipo de datos de estado selected es booleano, por lo que afecta a todos dateItem componentes de elementos de fecha que tiene. Tal vez sea mejor cambiar el estado selected a matriz o número.
Aquí hay un ejemplo si el tipo de datos de estado selected es número
estado seleccionado
const [selected, setSelected] = useState(null)componente principal
<View row style={{ flexWrap: "wrap" }}> {dayOfWeek.map((item, index) => ( <View> <DateItem days={item} index={index} selected={selected} setSelected={setSelected} /> </View> ))} </View>Componente dateItem
const DateItem = (props) => { const { days, selected, setSelected, index } = props return ( <TouchableOpacity row center onPress={() => { setSelected(index) }} style={selected !== index ? CONTAINER_WITHOUT_SELECTED : CONTAINER_WITH_SELECTED} > <Text style={selected !== index ? TEXT_WITHOUT_SELECTED : TEXT_WITH_SELECTED}>{days}</Text> {selected === index && <Icon name="check" color="white" />} </TouchableOpacity> ) } export default DateItemDebe configurar estados individuales para cada botón.
La forma en que su código funciona ahora, todos los botones manejan el mismo estado , es por eso que cada vez que hace clic en cualquiera de ellos, el estado cambia para todos ellos.
Una posible solución sería cambiar su estado de un solo valor booleano a un objeto de valores booleanos, o incluso a una matriz.
const [selected, setSelected] = useState([false,false,false,false,false,false,false])o incluso
const [selected, setSelected] = useState([monday: false, tuesday: false,wednesday: false, thursday: false, friday: false, saturday: false, sunday: false]) Y dentro de su .map() puede usar el index para cambiar el valor deseado