【问题标题】:Material UI select not showing label材质 UI 选择不显示标签
【发布时间】:2018-12-09 15:58:29
【问题描述】:

我在 Material UI 的“选择”上玩得很开心 - 花了大约 10 个小时才试图让一个按我喜欢的方式工作。非常感谢您的帮助。

这个问题与前一个问题有关:Select MenuItem doesn't show when JSX saved to state,我怀疑如果回答了“为什么”,我可能会更好地了解正在发生的事情。

我想要完成的是拥有一个可以执行以下正常操作的 Select:

  • 拥有所有 UI 好东西(在选择位置显示问题,然后 在您选择一个 非空选择)
  • 选择某项后,标签会出现(正如人们在 下拉)而不是空白(正如我所经历的那样 - 检查 上一个问题)
  • 控制台中没有关于“值”未定义的警告
  • 当我在选择某些内容后单击离开选择时,我没有 希望问题标签回到答案的顶部,如下所示:
  • 我想要一个“无”选项,将选择返回为“空” 表格(也就是说,问题标签以正常大小显示在 选择)
  • 我可以设置一个默认选中的选项

这些不应该是艰巨的任务,但我一辈子都做不到。挺尴尬的。

  • 然后,在选择某些内容时,我想保存该选择(连同 与其他选择选项)状态(所以我可以将其保存到 localStorage,因此较大的表单不会在页面刷新时“重置”)

无论哪种方式,我目前都有这个 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>

handleSelectChange 看起来像这样 - 再次,与材质 UI 演示完全相同。

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

除了控制台之外的这种工作给我以下错误:

失败的道具类型:道具value被标记为必填项 SelectInput,但其值为undefined。

点击离开后,选中的选项和问题标签会相互叠加,如下所示:

此外,如果我尝试添加此代码(在 componentDidMount 函数中)以能够传入“选定”/默认选项...

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});
        }
    }
}

它不会更新给我一个默认答案,并且还会在控制台中给我以下附加错误(除了上述所有问题):

警告:组件正在更改隐藏类型的不受控制的输入 被控制。输入元素不应从不受控制的状态切换 控制(反之亦然)。决定使用受控或 在组件的生命周期内不受控制的输入元素。

我错过了什么?

【问题讨论】:

    标签: javascript reactjs material-ui


    【解决方案1】:

    我不确定为什么上述解决方案不起作用。

    但是,我使用以下函数重建了 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;
    }
    

    我的渲染现在看起来像这样:

    <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>
    

    事件处理程序如下所示:

    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)
        );
    };
    

    传递给该对象的 props 如下所示:

    {
        "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"
    }
    

    对我来说,其中一个关键概念是了解Select 元素上的value 字段应该指向this.state 中的一个项目。然后,onChange 需要将该状态变量的名称(令人困惑的是,我将其命名为“值”)传递给 eventHandler 函数。

    handleSelectChange 函数的双箭头函数头(curried 函数)仍然让我感到困惑......(我不明白 'event' 属性是如何到达那里的,因为我用一个单参数)...但这目前有效,我可以尝试在将来的某个日期重构为我熟悉的语法(即:function(a, b) { *do something* })。 (是的....)

    【讨论】:

      【解决方案2】:

      只需在构造函数中定义 selectLabel:

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

      【讨论】:

        【解决方案3】:

        添加类radio_label:

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

        添加css属性:

        .radio_label{
            color:black
        }
        

        【讨论】:

        • 虽然此代码可以解决问题,including an explanation 说明如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。
        猜你喜欢
        • 1970-01-01
        • 2022-07-28
        • 2020-12-03
        • 1970-01-01
        • 1970-01-01
        • 2019-07-16
        • 2020-11-26
        • 2022-01-02
        • 2020-06-13
        相关资源
        最近更新 更多