在下拉列表中选择选项时,如何使用onChange更改状态,但使用选项标记内的值以外的值

问题描述 投票:1回答:3

下拉列表需要一些帮助。我似乎无法找到一种方法来传递特定于特定下拉列表<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>标记之间未显示的特定值的正确方法是什么?

javascript reactjs select dropdown
3个回答
2
投票

您可以将选项保留在组件状态中,并使用数组方法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>

1
投票

您可以将该值传递给显示选项的循环。

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

1
投票

有没有办法从每个下拉列表中读取一个未显示的值(从e.target.value中读取),即。如果他们每个人都有ID或其他东西,我该如何传递,以便e.target.value能够访问此ID。

e.targetHTMLSelectElement发生的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>
© www.soinside.com 2019 - 2024. All rights reserved.