选择组件的 inputProps (Material UI)

IT技术 reactjs material-ui
2021-05-25 04:45:43

此问题之后,我想替换 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 的数据属性是未定义的,这是为什么呢?

这是我测试此行为的代码和框:https ://codesandbox.io/s/dynamic-form-change-handler-with-select-ft4dj

1个回答

对于 Material-UI 的Select,触发 的事件onChange实际上是单击MenuItem这是该代码的稍微简化(忽略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属性的对象原始点击事件目标通常不会有帮助,因为它不会对应于表示 的一致 DOM 元素Select,而是对应于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

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