下拉列表需要一些帮助。我似乎无法找到一种方法来传递特定于特定下拉列表<option>
的ID,以便当用户进行选择时可以使用该值(例如setState
)。通常的情况是读取下拉列表本身的值,但在我的情况下,我不希望显示的值,而是另一个“幕后”或隐藏的值。
请注意我已经研究了有关控制组件的反应形式等,这个问题有点不同,我试图找到答案的空白。
我正在使用react和javascript,但我想如果你对javascript有所了解,你可以提供帮助。
下拉菜单设置如下所示,在更改下拉列表选项时,它运行函数handleStatusChange
。
<select
id="inputIdentity"
className="select-form"
onChange={this.handleStatusChange}
>
<option value="" hidden>
please choose
</option>
<option>status1</option>
<option>status2</option>
<option>status3</option>
</select>
在实际操作中,选项是从通过api获取的数据中映射出来的,因为它们可以在后端进行更改:
<select
id="inputIdentity"
className="form-control content-input"
onChange={this.handleStatusChange}
>
<option value="" hidden>
Please Choose
</option>
{statusData ? (
statusData.map((status) => (
<option>{status.title}</option>
))
) : (
<option>Loading...</option>
)}
</select>
this.handleStatusChange
检查事件的值(这是更改下拉列表中的选择的行为,使用:e.target.value
访问该值)以读取所选的<option>
内的值...读取所选下拉值的方法是就像是:
handleStatusChange = (e) => {
this.setState({
// set it to state
status: e.target.value
});
};
I
这是执行此操作的标准方法。
现在我们回到这个问题 - 有没有办法从每个下拉列表中读取一个未显示的值(从e.target.value中读取),即。如果他们每个人都有ID或其他东西,我该如何传递,以便e.target.value能够访问此ID。
如果你看看我映射出来的版本(或者如果你不熟悉map
函数就循环出来)<option>
标签,并且在每次迭代中我都用title
传递{status.title}
。我可以使用id
访问status.id
但是onChange处理程序在<select>
标记中并且不能在map
/ loop中,因此通过将id传入onChange处理程序来处理它也是不可能的。
onChange处理程序有权访问<option>
标记之间未显示的特定值的正确方法是什么?
您可以将选项保留在组件状态中,并使用数组方法find
查找与所选选项对应的选项并使用该选项。
例
class App extends React.Component {
state = {
options: [
{ value: "status1", label: "Status 1", secretValue: "foo" },
{ value: "status2", label: "Status 2", secretValue: "bar" },
{ value: "status3", label: "Status 3", secretValue: "baz" }
],
selectedOption: ""
};
handleStatusChange = e => {
const { value } = e.target;
this.setState(prevState => {
const { secretValue } = prevState.options.find(
option => option.value === value
);
console.log(secretValue);
return { selectedOption: value };
});
};
render() {
const { options, selectedOption } = this.state;
return (
<select value={selectedOption} onChange={this.handleStatusChange}>
<option value="" hidden>
please choose
</option>
{options.map(option => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
您可以将该值传递给显示选项的循环。
{statusData ? (
statusData.map((status) => (
<option value={status.value}>{status.title}</option>
))
) : (
<option>Loading...</option>
)}
为了做到这一点,你必须修改你的阵列statusData
。
hiddenData = ['a', 'b', 'c'];
statusData.map((s, index) => {
s.value = hiddenData[index]
return s;
});
有没有办法从每个下拉列表中读取一个未显示的值(从e.target.value中读取),即。如果他们每个人都有ID或其他东西,我该如何传递,以便e.target.value能够访问此ID。
e.target
是HTMLSelectElement
发生的change
的参考。你可以在option
列表中找到与value
匹配的options
,然后使用HTMLOptionElement
的属性,如下所示:
handleStatusChange({target}) {
const value = target.value;
const optionElement = Array.from(target.options).find(opt => opt.value === value);
// If found, use information from `optionElement` to find the
// entry in `statusData` in a state change, e.g.:
if (optionElement) {
const id = optionElement && optionElement.id;
if (id) {
this.setState(state => {
const entry = state.statusData.find(e => e.id === id);
if (entry) {
// Use `entry`'s information
}
}
}
}
}
反应示例,在details
中的条目上使用statusData
属性:
class Example extends React.Component {
constructor(...args) {
super(...args);
this.handleStatusChange = this.handleStatusChange.bind(this);
this.state = {
detail: "",
statusData: [
{id: "one", title: "One", detail: "Details for one"},
{id: "two", title: "Two", detail: "Details for two"},
{id: "three", title: "Three", detail: "Details for three"}
]
};
}
handleStatusChange({target}) {
const value = target.value;
const optionElement = Array.from(target.options).find(opt => opt.value === value);
const id = optionElement && optionElement.id;
if (id) {
this.setState(state => {
const entry = state.statusData.find(e => e.id === id);
if (entry) {
return {
detail: entry.detail
}
}
});
}
}
render() {
const {statusData, detail} = this.state;
return (
<div>
<select
id="inputIdentity"
className="form-control content-input"
onChange={this.handleStatusChange}
>
<option value="" hidden>
Please Choose
</option>
{statusData ? (
statusData.map((status) => (
<option id={status.id}>{status.title}</option>
))
) : (
<option>Loading...</option>
)}
</select>
<div>Detail: {detail}</div>
</div>
);
}
}
ReactDOM.render(
<Example />,
document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>