无法获取 material-ui select react 组件的目标属性
Can't get the target attributes of material-ui select react component
我正在尝试从 Material-UI 反应组件的 Select 字段元素中获取 ID、名称和值。
这是我的容器:
//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>
。有谁知道为什么?如果我使用普通的 select 字段(而不是 material-ui),那么这将按预期工作(即我可以获得 ID、名称、selected 选项的正确值).如何从 Material-UI Select 组件的 onChange 事件中获取目标 ID、名称等?
P.S 我对 material-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
};
更新 2
回复您的评论:
根据 material-ui docs,希望在选项元素而不是 select 元素上返回触摸事件。如果你想要元素的 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
}
并且当你附加到select组件时,你需要使用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. Under the event-pooling you will find reference to the use of e.persists()
in the block quote. The explanation given in this issue 是 React 池事件对象,所以当另一个事件被触发时它会被重用。
React 有一个比较特殊的事件对象。它将本机事件包装在合成事件中,这是 event
在您的 _onChange
方法中指向的内容。
问题是这个合成事件对象被回收并重新用于下一个事件,因此它被垃圾收集并设置为 null。我认为这没有很好的记录,但我会搜索 link 并在找到后更新此答案。
解决方案是让事件处理程序中的第一行复制事件、保留它或获取对本机事件的引用:
复制活动
_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);
};
我会使用 event.currentTarget
而不是 event.target
来简化它。
在您的事件处理程序中,您可以通过以下方式从触发事件的元素访问感兴趣的属性:
_onChange(evt) {
console.log(evt.currentTarget.getAttribute("data-name");
console.log(evt.currentTarget.getAttribute("data-value");
}
因此在 "data-"
前缀的属性名称上调用 .getAttribute
这是对 Material UI 和 React (2020) 最新版本的回答:
您的 <Select>
元素需要 name
属性。该名称值应对应于对象中的字段名称。
这应该有效(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}
>
但这行不通(名称被省略)。这将 return 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}
>
我正在尝试从 Material-UI 反应组件的 Select 字段元素中获取 ID、名称和值。
这是我的容器:
//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>
。有谁知道为什么?如果我使用普通的 select 字段(而不是 material-ui),那么这将按预期工作(即我可以获得 ID、名称、selected 选项的正确值).如何从 Material-UI Select 组件的 onChange 事件中获取目标 ID、名称等?
P.S 我对 material-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
};
更新 2
回复您的评论:
根据 material-ui docs,希望在选项元素而不是 select 元素上返回触摸事件。如果你想要元素的 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
}
并且当你附加到select组件时,你需要使用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. Under the event-pooling you will find reference to the use of e.persists()
in the block quote. The explanation given in this issue 是 React 池事件对象,所以当另一个事件被触发时它会被重用。
React 有一个比较特殊的事件对象。它将本机事件包装在合成事件中,这是 event
在您的 _onChange
方法中指向的内容。
问题是这个合成事件对象被回收并重新用于下一个事件,因此它被垃圾收集并设置为 null。我认为这没有很好的记录,但我会搜索 link 并在找到后更新此答案。
解决方案是让事件处理程序中的第一行复制事件、保留它或获取对本机事件的引用:
复制活动
_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);
};
我会使用 event.currentTarget
而不是 event.target
来简化它。
在您的事件处理程序中,您可以通过以下方式从触发事件的元素访问感兴趣的属性:
_onChange(evt) {
console.log(evt.currentTarget.getAttribute("data-name");
console.log(evt.currentTarget.getAttribute("data-value");
}
因此在 "data-"
前缀的属性名称上调用.getAttribute
这是对 Material UI 和 React (2020) 最新版本的回答:
您的 <Select>
元素需要 name
属性。该名称值应对应于对象中的字段名称。
这应该有效(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}
>
但这行不通(名称被省略)。这将 return 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}
>