在this question之后,我想替换TextField(输入年龄)组件以使用Select组件,因为我注意到两者都具有inputProps属性。
原始应用:
function App() {
const [state, setState] = React.useState({
cats: [{ name: "cat1", age: "2" }, { name: "cat2", age: "5" }],
owner: "Owner's Name"
});
const handleFormChange = e => {
if (["name", "age"].includes(e.target.dataset.fieldType)) {
const newCats = [...state.cats];
newCats[e.target.dataset.id][e.target.dataset.fieldType] = e.target.value;
setState({ ...state, cats: newCats });
} else {
setState({ ...state, [e.target.name]: e.target.value });
}
};
return (
<form onChange={handleFormChange}>
<TextField label="Owner" value={state.owner} name="owner" />
<br />
<br />
<TextField
label="Name 1"
value={state.cats[0].name}
inputProps={{ "data-id": 0, "data-field-type": "name" }}
/>
<TextField <-----------------------replace with a Select
label="Age 1"
value={state.cats[0].age}
inputProps={{ "data-id": 0, "data-field-type": "age" }}
/>
</form>
);
}
我将替换第二个TextField的Select组件:
<Select
onChange={handleSelectChange}
label={"Age 1"}
value={state.cats[0].age}
inputProps={{
"data-id": idx,
"data-field-type": "age",
name: "customName"
}}
>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
但是在我的handleSelectChange函数中:
const handleSelectChange = e => {
console.log("value", e.target.value); //OK
console.log("name", e.target.name); // OK
console.log("dataset", e.target.dataset); //undefined
};
传递给inputProps的数据属性是不确定的,为什么?
这是我用来测试此行为的codeandbox:https://codesandbox.io/s/dynamic-form-change-handler-with-select-ft4dj
答案 0 :(得分:1)
对于Material-UI的Select
,触发onChange
的事件实际上是单击MenuItem
的事件。这是that code的简化版本(忽略multiple
情况):
const handleItemClick = child => event => {
update(false, event);
if (onChange) {
const newValue = child.props.value;
event.persist();
event.target = { value: newValue, name };
onChange(event, child);
}
};
请注意,此处将事件目标明确创建为仅具有value
和name
属性的对象。原始点击事件目标通常不会有所帮助,因为它不会对应于表示Select
的一致DOM元素,而是会成为被点击的特定MenuItem
中的某些DOM元素。>
在回答您先前的问题时,我避免开始讨论本教程中的方法是否是一种好的方法,因为我想避免涉及更多基于观点的方面。但是,这种情况迫使讨论。通常,在React中,我认为最好避免在DOM中放入多余的内容,以便事件处理程序可以拉回信息。而是直接向事件处理程序提供信息。
例如,您可能拥有:
const handleSelectChange = (index, fieldType) => e => {
console.log("value", e.target.value);
console.log("name", e.target.name);
console.log("index", index);
console.log("fieldType", fieldType);
};
// then later in the JSX:
<Select
onChange={handleSelectChange(idx, "age")}
label={`Cat ${idx + 1} age`}
value={state.cats[idx].age}
inputProps={{
name: "customName"
}}
>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
在上面的代码段中,将索引和字段类型传递给handleSelectChange
以返回一个更改处理程序,该更改处理程序知道该信息,而不必成为DOM的一部分。
这是您的沙盒的修改版本,其工作原理如下:https://codesandbox.io/s/dynamic-form-change-handler-with-select-1sihp
同样的方法也可以用于文本输入。