#javascript #reactjs
#javascript #reactjs
Вопрос:
Всем привет!
Сегодня я пытаюсь создать выбираемый атрибут, например nike.com Air Force 1 страница товара в корзину
Я хочу выбрать один элемент и сохранить значение переключателя в состоянии.
Для этого я использую useRef
:
const getValueFromRadio = React.useRef(null)
Для вызова этих ссылок я использую onClick(myFunction)
тег label
<h1 className="text-center text-2xl">{product.name}</h1>
<div>
<div className={'block my-3'}>
{product.attribute !== undefined ? product.attribute.map((item, index) => <div className={'inline-block'} key={index}>
<label onClick={labelOnclickHandler} className="cursor-pointer py-2 px-3 my-3 mx-2 border border-grey-500 hover:border-black h-3 rounded" htmlFor={item.id}>{item.value}</label>
<input className="hidden" ref={getValueFromRadio} type="radio" id={item.id} value={item.value} name={'selectSize'}/>
</div>)
: null}
</div>
</div>
// sorry for the piss of shit indentation.
Если у меня есть только один атрибут, ссылка получит S
размер, а значение, которое я сохраняю в своем состоянии, равно S:
const labelOnclickHandler = (e) => {
const el = e.target.classList
if (el.contains('border-grey-500')){ //toggling.
el.remove('border-grey-500')
el.add('border-black')
} else {
el.add('border-grey-500')
el.remove('border-black')
}
setPrevElement(el) // get preview el for remove the border black.
setSelectSize(getValueFromRadio.current.value) // state to cart.
}
Но если у меня есть несколько атрибутов, реакция или ссылки возвращают меня каждый раз, когда «M», и я не знаю, является ли это ошибкой или это не лучший способ сделать это.
Ответ №1:
Вы можете использовать htmlFor
on <label>
, а затем, когда вы нажимаете на эту метку, вы запускаете ввод, если htmlFor
атрибут равен вводу ID
.
Затем вы можете обработать изменение состояния с onChange
помощью события RadioButton:
<label htmlFor={item.id}>
<input
id={item.id}
type='radio'
onChange={() => radioChangeHandler(item.id)}
/>
</label>
И затем:
const radioChangeHandle = (id) => {
setRadioState(id);
}
Таким образом, вы могли бы переключать свои классы по-другому, например:
className={` ${ RadioState === item.id ? "border-black" : "border-grey-500" } cursor-pointer py-2 px-3`}
Комментарии:
1. хорошо, но с вашим кодом мне нужен новый функциональный компонент? Я не думаю, что они будут иметь одинаковое состояние?
2. Но я пытаюсь это сейчас, я вернусь к вам 😁
Ответ №2:
Другое решение — передать индекс выбранного элемента:
const labelOnclickHandler = (e, index) => {
const el = e.target.classList
if (el.contains('border-grey-500')){ //toggling.
el.remove('border-grey-500')
el.add('border-black')
} else {
el.add('border-grey-500')
el.remove('border-black')
}
setPrevElement(el) // get preview el for remove the border black.
setSelectSize(product.attribute[index].value) // state to cart.
}
И вам не нужно использовать ссылку:
<div>
<div className={"block my-3"}>
{product.attribute !== undefined
? product.attribute.map((item, index) => (
<div className={"inline-block"} key={index}>
<label
onClick={(e)=> labelOnclickHandler(e, index)}
className="cursor-pointer py-2 px-3 my-3 mx-2 border border-grey-500 hover:border-black h-3 rounded"
htmlFor={item.id}
>
{item.value}
</label>
<input
className="hidden"
type="radio"
id={item.id}
value={item.value}
name={"selectSize"}
/>
</div>
))
: null}
</div>
</div>
Я рекомендую вам избегать использования индекса в качестве значения ключа (key={index}). Больше информации здесь https://reactjs.org/docs/lists-and-keys.html
Может быть, вы можете использовать key={`product_attribute_${index}`}