无法获得material-ui select react组件的目标属性

时间:2016-08-22 09:53:36

标签: reactjs material-ui

我试图从Material-UI反应组件的Select字段元素中获取id,name和value。

这是我的容器:

//some code is removed to keep things simple
class MyContainer extends Component {

  constructor(props) {
    super(props);
  }

  render() {
    return(
        <MyComp onChange={this._onChange.bind(this)}  />
    );
  }

  _onChange(evt) {
    console.log(evt.target); 
    console.log(evt.target.id);  //blank
    console.log(evt.target.name); //undefined 
    console.log(evt.target.value); //html value of selected option!

  }

 }
 export default connect(select)(MyContainer);

在我的演示组成部分:

  import React, {Component} from 'react';
  import Select from 'material-ui/SelectField';
  import MenuItem from 'material-ui/MenuItem';

  const someData = ["aaaa", "bbbb", "ccccc"];

  class MyComp extends Component {

    render() {
      const {onChange} = this.props;

      return (
        <form >
            <Select
                    value={this.props.test}
                    name={"test"}
                    id={"test"}
                    onChange={this.props.onChange}
                    hintText={"Select a fitch rating service"}>
              {
                someData.map((e) => {
                  return <MenuItem key={Math.random()}  value={e} primaryText={e}/>
                })
              }
            </Select>
        </form>
      );
    }
  }

问题是_onChange(evt)给出了这个值:

  evt.id is blank
  evt.name is undefined
  evt.target.value is <div>whatever the selected value was</div> 

似乎_onChange(evt)传递的参数不是SELECT,而是选项,因为当我打印evt.target时,它会给<div>whatever the selected value was</div>。有谁知道为什么?如果我使用普通的选择字段(不是material-ui),那么这可以按预期工作(即我可以获得id,name,所选选项的正确值)。如何从Material-UI Select组件的onChange事件中获取目标id,name..etc?

P.S我对材料-ui的TextField组件使用相同的_onChange方法,并且在那里工作。我也试过了:

 _onChange = (event, index, value) => {
    console.log(event.target.id); //blank
    console.log(event.target.name); //undefined
    console.log(index); //correct index
    console.log(value); //correct value
  };

3 个答案:

答案 0 :(得分:4)

更新2

回应你的意见:

根据material-ui docs,期望在选项元素而不是select元素上返回touchtap事件。如果你想要元素的id和名称,我建议将变量绑定到回调:

父组件中的onchange方法:

_onChange(id, name, evt, key, payload) {

  console.log(id);  //id of select
  console.log(name); //name of name
  console.log(payload); //value of selected option
}

当您将其附加到选择组件时,您需要使用bind

   <Select
     value={this.props.test}
     name={"test"}
     id={"test"}
     onChange={this.props.onChange.bind(null,"id","name")}
     hintText={"Select a fitch rating service"}>

更新

以下是react event docs。在事件池下,您将在块引用中找到e.persists()的使用参考。这个issue中给出的解释是React汇集了事件对象,因此在触发另一个事件时会重用它。

React有一个相当特殊的事件对象。它将本机事件包装在合成事件中,这是event方法中_onChange指向的事件。 问题是这个合成事件对象被回收并重用于下一个事件,因此它被垃圾收集并设置为null。我不认为这是有详细记录的,但我会在找到链接后更新此答案。

解决方案是针对事件处理程序中的第一行创建事件的副本,保留事件或获取对本机事件的引用:

制作活动的副本

_onChange = (event, index, value) => {
  e = _.cloneDeep(event); // Here I'm using the cloneDeep method provided by underscore / lodash . User whatever library you prefer. 
  console.log(e.target.id); 
  console.log(e.target.name); 
};

坚持事件

_onChange = (event, index, value) => {
  event.persist() // This stops react from garbage collecting the event object. It may impact performance, but I doubt by much.
  console.log(event.target.id); 
  console.log(event.target.name); 
};

获取对本机事件对象的引用

_onChange = (event, index, value) => {
  e = event.native; // This looks the same as a vanilla JS event
  console.log(e.target.id); 
  console.log(e.target.name); 
};

答案 1 :(得分:2)

我将使用D:\temp>cd test D:\temp\test>npm start > test@0.1.0 start D:\temp\test > react-scripts start [ screen wipe ] Compiled successfully! You can now view test in the browser. http://localhost:3000 Note that the development build is not optimized. To create a production build, use npm run build. 而不是event.currentTarget使其更简单。 在事件处理程序中,您可以通过以下方式从触发事件的元素中访问感兴趣的属性:

event.target

因此在以“ data-”开头的属性名称上调用_onChange(evt) { console.log(evt.currentTarget.getAttribute("data-name"); console.log(evt.currentTarget.getAttribute("data-value"); }

答案 2 :(得分:1)

这是Material UI和React(2020)最新版本的答案:

您需要在name元素上拥有<Select>属性。该名称值应与对象中字段的名称相对应。

这应该可行(name设置为您要更新的字段):

 <Select
            labelId="demo-simple-select-outlined-label"
            id="demo-simple-select-outlined"
            name="taskType"
            value={props.job.taskType || ""}
            label="{props.label}"
            onChange={props.onTaskTypeChange}
          >

但这不起作用(名称被省略)。这将返回evt.target.name = undefined

 <Select
            labelId="demo-simple-select-outlined-label"
            id="demo-simple-select-outlined"
            value={props.job.taskType || ""}
            label="{props.label}"
            onChange={props.onTaskTypeChange}
          >