带有多个变量的ReactJS单选按钮组

时间:2018-08-20 10:18:40

标签: javascript reactjs radio

我试图像这样在ReactJS中建立一个Radiobutton-Group: enter image description here

我也在使用Bootstrap自定义单选按钮。

首先,我制作了此组件:

import React from "react";
import ReactDOM from 'react-dom';
import PropTypes from "prop-types";
import FormsStatic from "../FormsStatic";

class IPMRadiobutton extends React.Component {
    constructor(props) {
        super(props);
    }
    render() {
        const uniqueId = FormsStatic.guid();
        return (
            <div className="custom-control custom-radio">
                <input
                    type="radio"
                    className="custom-control-input"
                    id={"others-" + uniqueId}
                    checked={this.props.checked}
                    onChange={this.props.onChange}
                    disabled={this.props.readOnly}
                />
                <label className="custom-control-label" style={{ 'fontWeight': 'normal' }} htmlFor={"others-" + uniqueId}>
                    <p>{this.props.description ? this.props.description : ""}</p>
                </label>
            </div>
        );
    }
}

IPMRadiobutton.propTypes = {
    className: PropTypes.string,
    onChange: PropTypes.func,
    readOnly: PropTypes.bool,
    description: PropTypes.string,
    checked: PropTypes.bool
}

export default IPMRadiobutton;

现在我要像这样使用此单选按钮:

   <IPMRadiobutton {...this.props.formControlProps} checked={variable1} description="H-Akte" name="Akte" onChange={() => { console.log("Do i have to change the variable1 and variable2 here?") }} />
   <IPMRadiobutton {...this.props.formControlProps} checked={variable2} description="U-Akte" name="Akte" onChange={() => { console.log("Do i have to change the variable1 and variable2 here?") }} />

我的问题是,每个单选按钮都应绑定到一个变量(或者在“ onChange-event”中更改其他单选按钮的所有变量)。因此,如果我检查了第一个单选按钮,则variable1应该设置为true,variable2应该设置为false。

如何使用组件完成此任务?

还是有更好的方法(例如,完整的其他概念)?

1 个答案:

答案 0 :(得分:0)

如果您需要在某个非常重要的项目中进行制作,我建议您为此使用一些react插件。您可以在那里找到它,相信我。但是如果您对React进行修改,可以享受时间编码,您可以查看我的示例(难看但有些想法)。

您可以使用此想法创建自己的RadioGroup组件。将options传递给RadioGroup并让该组件根据该属性呈现无线电输入似乎是解决此问题的简便方法。我觉得很容易申请。

我认为将值传递给RadioGroup组件并通过将onChange回调传递给该组件来更新值是一件好事,因为无论如何您也想保存此值,而且也不会在RadioGroup组件内部存储内部值,这会使它变得更加被动简化与外部源的值同步。

作为奖励,我已经向RadioGroup添加了multiSelect道具,只是为了好玩! 你觉得怎么样,丹尼尔?

class RadioOption extends React.Component {
    constructor(props) {
        super(props)

        this.onChange = this.onChange.bind(this)
    }
    render() {
        const { onChange, option: { description, ...restOptionProps }, ...restProps } = this.props
        return (
            <div className="custom-control custom-radio">
                <input
                    type="radio"
                    className="custom-control-input"
                    onChange={this.onChange}
                    {...restProps}
                    {...restOptionProps}
                />
                <label className="custom-control-label" style={{ 'fontWeight': 'normal' }} htmlFor={this.props.option.id}>
                    <p>{description ? description : ""}</p>
                </label>
            </div>
        )

    }

    onChange() {
        this.props.onToggle(this.props.option)
    }

}


class IPMRadioGroup extends React.Component {
    constructor(props) {
        super(props)


        this.onRadioOptionToggle = this.onRadioOptionToggle.bind(this)
        this.isChecked = this.isChecked.bind(this)
    }
    render() {
        return (
            <div className="radio-group-container">
                {this.props.options.map(option => {
                    return (
                        <RadioOption checked={this.isChecked(option)} key={option.id} onToggle={this.onRadioOptionToggle} option={option} />
                    )
                })}
            </div>
        )
    }

    isChecked(option) {

        return this.props.value.some(currentOption => option.id === currentOption.id)

    }

    onRadioOptionToggle(option) {

        let value = [].concat(this.props.value)
        let valueFound = false;
        let updatedValue = value.reduce((values, currentValue) => {

            if (currentValue.id === option.id) {
                valueFound = true;
                return values
            }

            if (!this.props.multiSelect) {
                return values
            }

            return values.concat(currentValue)
        }, [])

        if (!valueFound) { updatedValue.push(option) }
        this.props.onChange(updatedValue)

    }

}

IPMRadioGroup.defaultProps = {
    value: [],
    multiSelect: false,
}




class Example extends React.Component {

    constructor(props) {
        super(props)
        this.state = {
            radioGroupValue: []
        }
        this.onRadioGroupChange = this.onRadioGroupChange.bind(this)
    }

    render() {
        return (
        <div>
            <IPMRadioGroup onChange={this.onRadioGroupChange} value={this.state.radioGroupValue} options={[
                { description: 'test1', id: "uniqueId1", disabled: true },
                { description: 'test2', id: "uniqueId2" },
                { description: 'test3', id: "uniqueId3" },
            ]} />
            Current Selection {JSON.stringify(this.state.radioGroupValue)}
            </div>
        )
    }

    onRadioGroupChange(value) {
        this.setState({radioGroupValue:value})
    }

}

ReactDOM.render(<Example />, document.getElementById('example'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>

<div id="example"></div>

作为旁注,我使用了一些很酷的功能,例如:

我喜欢道具类型的用法!干杯!