选择组件的inputProps(材料UI)

时间:2019-07-17 14:39:35

标签: material-ui

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

1 个答案:

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

请注意,此处将事件目标明确创建为仅具有valuename属性的对象。原始点击事件目标通常不会有所帮助,因为它不会对应于表示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

同样的方法也可以用于文本输入。