【问题标题】:Reactjs with LinkedStateMixin and select with multiple optionsReactjs 与 LinkedStateMixin 并选择多个选项
【发布时间】:2014-08-19 16:29:13
【问题描述】:

使用 Reactjs,我希望有一个 handleChange 方法来处理我的所有表单元素的修改。

我知道 LinkedStateMixin 就是因为这个原因而存在的,我应该使用

render: function() {
    return <select multiple={{ true }} valueLink={this.linkState('value')}>...options...</select>;
  }

绑定我的选择元素的状态。

但似乎这种处理方式不适用于多个选择:state.value 已更新但只有一个值(当我选择 2 个选项时,我可以看到 React 更新了 DOM,它系统地删除了其中一个选择)。

所以我的问题是:LinkedStateMixin 是这个用例的死胡同吗?您如何处理这种多选用例?

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    根本问题是.value 对于具有multiple 属性的选择元素只返回它包含的第一个选定选项元素的值。因此,当 ValueLink mixin 调用 event.target.value 以获取 select 的新值时,它不会返回使 value 属性工作所需的数组。

    您可以围绕select 构建一个小包装器来完成这项工作;这是我的版本 (plus a JSFiddle example):

    // A select element that supports `multiple` and `valueLink` correctly
    var BetterSelect = React.createClass({
      render: function() {
        if (this.props.valueLink) {
          return this.transferPropsTo(
            <select value={this.props.valueLink.value}
                    valueLink={null} onChange={this.handleChange}>
              {this.props.children}
            </select>
          );
        } else {
          return this.transferPropsTo(
            <select onChange={this.handleChange}>
              {this.props.children}
            </select>
          );
        }
      },
    
      handleChange: function(e) {
        var selectedValue;
        if (this.props.multiple) {
          // We have to iterate the `options` elements
          // to figure out which ones are selected.
          selectedValue = [];
          var options = e.target.options;
          for (var i = 0, l = options.length; i < l; i++) {
            if (options[i].selected) {
              selectedValue.push(options[i].value);
            }
          }
        } else {
          selectedValue = e.target.value;
        }
    
        // Fire onChange manually if it exists since we overwrote it
        this.props.onChange && this.props.onChange(e);
    
        // Finally, manually take care of any valueLink passed
        if (this.props.valueLink) {
          this.props.valueLink.requestChange(selectedValue);
        }
      }
    });
    
    
    // Let's try it out:
    var Application = React.createClass({
      mixins: [React.addons.LinkedStateMixin],
    
      getInitialState: function() {
        return { value: ['Apples', 'Oranges'] };
      },
    
      render: function() {
        return (
          <div>
            <pre>{JSON.stringify(this.state.value)}</pre>
            <BetterSelect multiple valueLink={this.linkState('value')}>
              <option value='Apples'>Apples</option>
              <option value='Bananas'>Bananas</option>
              <option value='Oranges'>Oranges</option>
            </BetterSelect>
          </div>
        );
      }
    });
    

    【讨论】:

    • 我不明白为什么 select "value" 属性在 multiple=true 时接受一个数组作为设置器;但仅在用作 getter 时返回第一个值;这感觉很奇怪。
    • 您在 react 组件上设置值,但来自 DOM 事件 event.target 是实际的 DOM 节点。
    • 我已经打开了一个问题,以便与 ReactLink 一起工作,顺便说一句:github.com/facebook/react/pull/1761
    • 好的,谢谢;我以为 Reactjs 已经将 value 映射到 selectedIndex 但我刚刚意识到 value 是 HTMLSelectElement developer.mozilla.org/fr/docs/Web/API/HTMLSelectElement 上的有效属性;太糟糕了 Reactjs 并没有在他们的 mixin 中隐藏这种复杂性
    猜你喜欢
    • 2019-08-22
    • 2019-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-15
    • 2019-10-13
    • 2015-07-24
    • 2022-07-16
    相关资源
    最近更新 更多