简体   繁体   English

材质 UI 选择不显示标签

[英]Material UI select not showing label

I'm having a heck of a time with Material UI's "Select" - about 10 hours into trying to get one working the way I'd like.我在 Material UI 的“选择”上玩得很开心 - 大约 10 个小时试图让一个人以我想要的方式工作。 I'd really appreciate some help.我真的很感激一些帮助。

This question is related to a previous one: Select MenuItem doesn't show when JSX saved to state and I suspect that if the "why" were answered on that, I might get a better idea of what's going on.这个问题与前一个问题有关: Select MenuItem 不显示 JSX 保存到状态的时间,我怀疑如果“为什么”得到了回答,我可能会更好地了解发生了什么。

What I'm trying to accomplish is having a Select that does the following normal things:我想要完成的是让 Select 执行以下正常操作:

  • has all the UI goodies (shows the question in the select spot, then moves the question smaller and out of the way after you select a non-null selection)拥有所有 UI 好东西(在选择位置显示问题,然后在选择非空选择后将问题移小并移开)
  • upon selecting something, the label shows up (as one would expect in a drop down) rather than a blank (as I have been experiencing - check previous question)选择某些内容后,标签会显示(正如人们在下拉列表中所期望的那样)而不是空白(正如我所经历的 - 检查上一个问题)
  • no warnings in the console about 'value' being undefined控制台中没有关于“值”未定义的警告
  • when I click away from the select after selecting something, I don't want the question label to move back on top of the answer like this:当我在选择某些内容后单击远离选择时,我不希望问题标签像这样移回答案的顶部: 选定的选项和问题标签在彼此之上
  • I want a 'none' option that returns the select back to it's "empty" form (That is to say, the question label shows at normal size in the select)我想要一个“无”选项,将选择返回到它的“空”形式(也就是说,问题标签在选择中以正常大小显示)
  • I can set a selection to be selected by default我可以设置一个选择以默认选择

These shouldn't be hard tasks, but I can't for the life of me get it.这些不应该是艰巨的任务,但我这辈子都做不到。 It' rather embarrassing.比较尴尬

  • Then, upon selecting something, I want to save that selection (along with the other selection options) to state (so I can save it to localStorage so the larger form doesn't 'reset' upon page refresh)然后,在选择某些内容时,我想将该选择(以及其他选择选项)保存到状态(以便我可以将其保存到 localStorage 以便较大的表单不会在页面刷新时“重置”)

Either way, I've currently got this JSX - effectively a cut-and-paste from the material ui demos with a map for the MenuItems :无论哪种方式,我目前都有这个 JSX - 有效地从材料 ui 演示中剪切和粘贴,带有MenuItems的地图:

<FormControl className={classes.formControl}>
<InputLabel htmlFor={this.props.label}>{this.props.label}</InputLabel>
<Select
    value={this.state.selectLabel}
    onChange={this.handleSelectChange}
    inputProps={{
        name: 'selectLabel',  
        id: this.props.label,
    }}
>
{this.props.value.map(valueLabelPair =>
                <MenuItem
                    key={this.props.XMLvalue + "_" + valueLabelPair.label}
                    value={valueLabelPair.value}
                >
                    {valueLabelPair.label}
                </MenuItem>
            )}
</Select>
</FormControl>

the handleSelectChange looks like this -- again, exactly the same as the material UI demo. handleSelectChange 看起来像这样——同样,与材质 UI 演示完全相同。

handleSelectChange = event => {
    this.setState({ [event.target.name]: event.target.value });
};

This kind of works except the console gives me the following error:这种工作除了控制台给我以下错误:

Failed prop type: The prop value is marked as required in SelectInput , but its value is undefined .失败的道具类型:道具valueSelectInput标记为 required ,但其值为undefined

and the selected option and question label go on top of each other after you click away, like so:单击离开后,所选选项和问题标签会重叠在一起,如下所示: 选定的选项和问题标签在彼此之上

Further, if I try to add in this code (in the componentDidMount function) with the goal of being able to pass in the 'selected'/default option...此外,如果我尝试添加此代码(在 componentDidMount 函数中),目标是能够传入“selected”/默认选项......

componentDidMount() {
    for (var i = 0; i < this.props.value.length; i++) {
        if(this.props.value[i].selected) {
            // *works* console.log("selected found: " + this.props.value[i].label);
            this.setState({selectLabel:this.props.value[i].label});
        }
    }
}

it does not update the give me a default answer and also gives me the following additional error in the console (in addition to all issues above):它不会更新给我一个默认答案,并且还会在控制台中给我以下附加错误(除了上述所有问题):

Warning: A component is changing an uncontrolled input of type hidden to be controlled.警告:组件正在将隐藏类型的不受控制的输入更改为受控制。 Input elements should not switch from uncontrolled to controlled (or vice versa).输入元素不应从不受控制切换到受控制(反之亦然)。 Decide between using a controlled or uncontrolled input element for the lifetime of the component.决定在组件的生命周期内使用受控或非受控输入元素。

What am I missing?我错过了什么?

Just define selectLabel into constructor:只需将selectLabel定义为构造函数:

constructor () {
    super()
    this.state = {
        selectLabel:'',
    }
}

I am unsure as to why the above solution did not work.我不确定为什么上述解决方案不起作用。

However, I rebuilt the Select to return "option" elements instead of "MenuItem" elements with the following function:但是,我使用以下功能重建了 Select 以返回“option”元素而不是“MenuItem”元素:

buildSelectOptions(optionsPairs) {  // note, this references props and blank option could be split out for reuse
    var JSX_return = [];

    if (this.props.includeBlank && this.props.includeBlank === true) {
        JSX_return.push(<option key="nada" value="" />);
    }

    for (var optionLabel in optionsPairs) {
        JSX_return.push(<option key={optionLabel} value={optionsPairs[optionLabel]}>{optionLabel}</option>);
    }
    return JSX_return;
}

My render now looks like this:我的渲染现在看起来像这样:

<FormControl className={classes.formControl}>
    <InputLabel htmlFor="age-native-simple">{this.props.label}</InputLabel>
    <Select
        native
        value={this.state.value}
        onChange={this.handleSelectChange('value')}
        inputProps={{
            name: this.props.label,
            id: this.props.id,
          }}
    >
        {this.buildSelectOptions(this.props.options)}

    </Select>
    <FormHelperText>{this.props.helperText}</FormHelperText>
</FormControl>

And the event handler looks like this:事件处理程序如下所示:

handleSelectChange = name => event => {  //FUTURE: combine the handlers  (or split out question types to sub-components)
    this.setState({ [name]: event.target.value },
        () => this.props.stateChangeHandler(this)
    );
};

the props passed to this object look like this:传递给此对象的道具如下所示:

{
    "key": "test4",
    "id": "test4",
    "label": "Question Label 4",
    "XMLValue": "XMLQ4",
    "type": "DropDown",
    "includeBlank": true,
    "helperText": "PCodes FTW!",
    "options": {
        "No oe": "NA",
        "My1": "One",
        "My2": "Two",
        "My3": "three"
    },
    "value": "One"
}

One of the key concepts for me was to learn that the value field on the Select element should be pointed at an item in this.state .我的一个关键概念是了解Select元素上的value字段应该指向this.state中的一个项目。 Then, the onChange needs to pass the name of that state variable (which, confusingly, I have named 'value') to the eventHandler function.然后,onChange 需要将该状态变量的名称(令人困惑的是,我将其命名为“value”)传递给 eventHandler 函数。

The double arrow function header (curried function) of the handleSelectChange function still confuses me... (I don't understand how the 'event' property is getting there, given I'm calling this function with a single parameter)... but this works for now and I can try to refactor into syntax I am comfortable with (ie: function(a, b) { *do something* } ) at some future date. handleSelectChange函数的双箭头函数头(柯里化函数)仍然让我感到困惑......(我不明白 'event' 属性是如何到达那里的,因为我用一个参数调用了这个函数)......但这现在有效,我可以尝试重构为我熟悉的语法(即: function(a, b) { *do something* } )在未来的某个日期。 (yeah....) (是的....)

Add class radio_label :添加类radio_label

<FormControlLabel value="male" label="Male" control={<Radio />}  className="radio_label"/>

Add css property :添加 css 属性:

.radio_label{
    color:black
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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