简体   繁体   English

选择组件的 inputProps (Material UI)

[英]Select Component's inputProps (Material UI)

Following this question , I would like to replace the TextField (to input the age) component to use a Select component since I notice both have the inputProps property.此问题之后,我想替换 TextField(输入年龄)组件以使用 Select 组件,因为我注意到它们都具有 inputProps 属性。

Original app:原始应用程序:

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

The Select component I'm replace the second TextField:我要替换第二个 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>

But in my handleSelectChange function:但是在我的 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
  };

The data attributes passed to the inputProps are undefined, why is that?传递给 inputProps 的数据属性是未定义的,这是为什么呢?

This is a codesandbox I made testing this behaviour: https://codesandbox.io/s/dynamic-form-change-handler-with-select-ft4dj这是我测试此行为的代码和框: https ://codesandbox.io/s/dynamic-form-change-handler-with-select-ft4dj

For Material-UI's Select , the event that triggers the onChange is actually a click on a MenuItem .对于 Material-UI 的Select ,触发onChange的事件实际上是单击MenuItem Here is a slightly simplified (ignoring the multiple case) version of 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);
    }
  };

Notice that the event target is explicitly created here as an object with only value and name properties.请注意,事件目标在此处显式创建为仅具有valuename属性的对象。 The original click event target would not generally be helpful since it wouldn't correspond to a consistent DOM element representing the Select , but would instead be some DOM element within the particular MenuItem that was clicked.原始的单击事件目标通常没有帮助,因为它不会对应于表示Select的一致 DOM 元素,而是对应于被单击的特定MenuItem中的某个 DOM 元素。

When answering your previous question, I avoided starting a discussion about whether the approach in the tutorial is a good one since I wanted to avoid getting into more opinion-based aspects;在回答您之前的问题时,我避免开始讨论本教程中的方法是否好,因为我想避免涉及更多基于意见的方面; however, this scenario forces the discussion.然而,这种情况迫使讨论。 In general, in React I think it is best to avoid putting extra stuff in the DOM so that event handlers can pull the information back out.一般来说,在 React 中,我认为最好避免在 DOM 中放入额外的东西,以便事件处理程序可以将信息拉回来。 Instead, just provide the event handler directly with the information.相反,只需直接向事件处理程序提供信息。

For instance you could have:例如你可以有:

  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>

In the code snippet above, the index and field type are passed to handleSelectChange to return a change handler that knows that information without it ever needing to be part of the DOM.在上面的代码片段中,索引和字段类型被传递给handleSelectChange以返回一个知道该信息的更改处理程序,而无需将其作为 DOM 的一部分。

Here's a modified version of your sandbox with this working: https://codesandbox.io/s/dynamic-form-change-handler-with-select-1sihp这是您的沙箱的修改版本: https : //codesandbox.io/s/dynamic-form-change-handler-with-select-1sihp

This same approach could also be used for the text inputs.同样的方法也可以用于文本输入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM