简体   繁体   中英

Selectable Inputs in react as checkboxes

Im trying to make a row of custom check boxes but I can't seem to trigger a change on selection:

在此处输入图片说明

I can get it to render with the correct default option but I cannnot trigger any change in selection. I was hoping to not use the native dropdown Select that react offers and wanted to build my own.

const getVariances = async () => {
    /// gets and sets list of variants ///
    setProductVariances(variances)
}
const changeVariance = (e) => {
    const { value } = e.target;
    const newProduct = productVariances.find(o => o.id == value)
    setSelected(newProduct.id)
    setProduct(newProduct)
}

return (
    <div className='product-variances'>
        {productVariances.length ? productVariances.map(variance => (
            <div key={variance.id} className="col-sm-3">
                <div className="quiz_card_area">
                    <input className="quiz_checkbox variance-checkbox" onChange={(e) => changeVariance(e)} type='checkbox' defaultChecked={product.id === variance.id} value={variance.id} />
                    <div className="single_quiz_card">
                        <div className="quiz_card_content">
                            <div className="quiz_card_title">
                                <h3><i className="fa fa-check" aria-hidden="true"></i>{variance.name}</h3>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        )) : null}
    </div>
)

}

Using 'onClick' to handle the action is not allowed with an input tag. Whats the best way to trigger the 'changeVariances' functionality with these custom check-boxes?

"onChange" always works for input elements. I had also created a custom MultiSelect for my app. I'm sure you will get value if you console.log in

const changeVariance = (e) => {
    console.log(e.target.value)
    const { value } = e.target;
    ....
}

By the looks of it, seems that you want a controlled component but you have not provided the checked attribute. I would suggest that you add it like this:

<input className="quiz_checkbox variance-checkbox" 
  onChange={changeVariance} 
  type='checkbox'
  value={variance.id} 
  checked={selected===variance.id} 
/>

Note the removal of defaultChecked which is used for uncontrolled components, where you need to specify the first value but let the DOM take care of further value updates. To specify the initial value, you should set it in the state (in your selected state variable)

Also, you don't need to pass an anonymous function to the onChange attribute, you can change it to: onChange={changeVariance} and it will work the same.

Also... Do you really need to keep two states, one for the selected variance id and another for the selected variance object? I suggest you keep just the one with the whole object. It would result in something like this:


const changeVariance = (e) => {
    const { value } = e.target;
    const newProduct = productVariances.find(o => o.id == value)
    setProduct(newProduct)
}

return (
    <div className='product-variances'>
        {productVariances.length ? productVariances.map(variance => (
            <div key={variance.id} className="col-sm-3">
                <div className="quiz_card_area">
                    <input className="quiz_checkbox variance-checkbox" 
                           onChange={changeVariance} 
                           type='checkbox' 
                           value={variance.id}
                           checked={variance.id === product.id} 
                    />
                    <div className="single_quiz_card">
                        <div className="quiz_card_content">
                            <div className="quiz_card_title">
                                <h3><i className="fa fa-check" aria-hidden="true"></i>{variance.name}</h3>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        )) : null}
    </div>
)

And lastly, I think you want radio buttons instead of checkboxes, because it seems like it doesn't make sense to check two variances at the same time! If you decide to use radio buttons, make sure to check for e.target.checked before updating state on the onChange function, otherwise it will not work because onChange will be triggered for both checked and unchecked radio.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM