【问题标题】:reactjs get select values - always undefinedreactjs获取选择值-始终未定义
【发布时间】:2016-11-03 20:36:47
【问题描述】:

我对 reactjs 很陌生,所以我写了一个相当简单的页面来测试“动态”<select> 选项以及如何获取所选值。我想做的是在提交时,能够通过迭代this.refs 来获取选定的值,但我得到的是未定义的值。我不确定如何使用手柄更改使其以受控方式工作,因此我选择采用不受控制的方法。但是我想知道如何做到这两种方式。或者是否有更简洁/首选的方式来获取表单提交时选择的值?

同样在select的渲染中,为什么我不能在那里添加ref={this.props.formId}而不是在OptionsList上?如果我删除 OptionsList 上的 ref 并将其放在选择中,则它不会识别任何选择输入。

var data1 = [
  { Id: 1, Name: "Option 1", Value: "Value 1" },
  { Id: 2, Name: "Option 2", Value: "Value 2" },
  { Id: 3, Name: "Option 3", Value: "Value 3" }
];

var data2 = [
  { Id: 4, Name: "Option 4", Value: "Value 4" },
  { Id: 5, Name: "Option 5", Value: "Value 5" },
  { Id: 6, Name: "Option 6", Value: "Value 6" }
];

var FormOptionList = React.createClass({
    handleSubmit: function (e) {
        e.preventDefault();

        for (var ref in this.refs) {
            console.log(this.refs[ref].value);
        }

        return;
    },
    render: function () {
        return (
          <div className="formList">
              <form onSubmit={this.handleSubmit}>
                  <div>
                    <OptionsList key="ListA" formId="ListA" options={this.props.data1} ref="ListA" />
                    <br />
                    <OptionsList key="ListB" formId="ListB" options={this.props.data2} ref="ListB" />
                  </div>
                  <input type="submit" value="Post" />
              </form>
          </div>
      );
    }
});

var OptionsList = React.createClass({
    //getInitialState: function () {
    //    return {
    //        options: [],
    //        selectValue: 'Option 1'
    //    };
    //},
    //handleChange: function(e) {
    //    this.setState({ selectValue: e.target.value })
    //},
    getInitialState: function () {
        return {
            options: []
        };
    },
    render: function () {
        var optionsList = this.props.options.map(function (option) {
            return (
                <option key={option.Id} value={option.Value}>{option.Name}</option>
            )
        });
        return (
            <select>
                {optionsList}
            </select>
        );
    }
});

ReactDOM.render(
  <FormOptionList data1={data1} data2={data2} />,
  document.getElementById('content')
);

【问题讨论】:

  • 正如@Vladimir 所说。在你的OptionsList:jsfiddle.net/ufL3071m写一个getter
  • 这很有帮助,谢谢

标签: reactjs reactjs.net


【解决方案1】:

使用 refs 并不是实现您想要的最佳方式。

一个好办法是

1º 在你的父组件中添加一个方法来存储你的&lt;OptionList&gt; 组件的值

handleSelectChange(select,value){
    this.setState({[select] : value})
}

2º 将handleSelectChange 作为道具传递给&lt;OptionList&gt;

<OptionsList key="ListA"
     formId="ListA" options={this.props.data1}
     onChange={this.handleSelectChange} />

3º 使用onChange + handleSelectChange&lt;select&gt; 值传递给父组件

var OptionsList = React.createClass({
    render: function () {
        var optionsList = this.props.options.map((option) => {
            return (
                <option key={option.Id} value={option.Value}>{option.Name}</option>
            )
        });
        return (
            <select onChange={(e) => this.props.onChange(this.props.formId,e.target.value)}>
                {optionsList}
            </select>
        );
    }
});

full working example

【讨论】:

  • 如果您有 X 个 OptionsList,即在 getInitialState 中没有硬编码 ListA、ListB,您将如何处理?
  • 你不需要初始状态,你可以在你的 OptionList componentDidMount 事件中设置初始值,它会自动添加到你的父状态中。jsfiddle.net/69z2wepo/47498
  • 我明白了,谢谢。如果我需要设置自定义初始状态,会在 OptionsList 中处理吗?同样通过反应,您是否只是将 onChange 事件从 OptionsList 传播到 FormOptionList OptionsList 的 onChange 事件中,如果存在父/子关系,这是否是标准做法?假设我有一个 ,我会在其中有一个 onChange 事件,在父级中有另一个 onChange 并使用类似 this.handleTextboxChange?
  • 是的,初始状态将在 OptionList componentDidMount/componentWillMount 中处理(我更新了 jsfiddle)。关于第二个问题,这是一个很好的做法,在 React 中有两种类型的组件,“容器”组件和“展示”组件。解释有点长,但你可以在这里阅读,medium.com/@dan_abramov/…
  • 谢谢,这很有帮助。
【解决方案2】:

您获得undefineds 的原因是因为您在refs 中拥有的是您的自定义组件OptionsList 的实例,而不是DOM 元素。这通常适用于 React,如果您在 DOM 元素 (&lt;div ref="myDiv" /&gt;) 上放置一个 ref,那么 this.refs.myDiv 将为您提供此 div 的实际物理 DOM 元素。相反,如果您将ref 放在自定义组件上,就像您所做的那样,那么ref 会保存该组件的一个实例。 OptionsList 没有称为 value 的方法或属性,因此是 undefineds。这也应该解决您的第二个问题-每个组件都有自己的refs-当您在OptionsList 中的select 上放置ref 时,它只能在OptionsList 内访问。

为了完成这项工作,您需要在 OptionsList 上公开一些 API 以获取值然后使用它,例如

{
  ...
  render(){ 
    return (
            ...
            <select ref='select'>
                {optionsList}
            </select>
        );
 },

  getValue(){ return this.refs.select.value; }
}

然后在FormOptionListconsole.log(this.refs[ref].getValue());

以受控方式执行此操作将涉及在 OptionsList 上定义 valueonChange 属性 - 您或多或少只是将它们传递给 select。然后在FormOptionList(或其祖先之一)中,您需要拥有value 的状态并使用OptionsListvalueonChange 以保持此值与@987654350 同步@。

希望这是有道理的:-)

【讨论】:

  • 我在第二句话中记下了这一点,假设我从 OptionsList 中删除了 ref 并且在选择中我现在在 getValue( ),当它是道具时,我如何获得价值?返回 this.refs[this.props.formId].value ?
  • 是的,这应该仍然有效,但我会小心让道具指定参考的名称,因为道具可以及时改变。通常最好使用您可以控制的静态值。
【解决方案3】:

在您的选择对象中(假设您使用的是 express body-parser)您需要分配一个名称属性,例如,看我的代码

    <select required name='gender' className={classes.selectBox} >
          <option value='NotSelected' >-------</option>
          <option value='Male' >Male</option>
          <option value='Female'>Female</option>
    </select>

要获取此输入值的值,请在 POST 处理程序中运行以下命令

let {gender, <any other name attributes in your POST form>} = req.body;

然后就可以了!您将获得一个 JSON 对象,其名称为键,值与其关联。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-15
    • 2022-11-29
    • 2017-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多