繁体   English   中英

反应下拉菜单选择-基于箭头按钮的增加或减少

[英]React Dropdown Selection - Increment or Decrement based on arrow button click

我有一个下拉输入。 单击输入旁边的向左或向右箭头按钮时,我想向前或向后移动当前选择的选项。 单击下拉列表本身并选择一个选项时,它还应该跟踪该选项。

使用e.target.value(和控制台日志)单击时,我能够捕获当前所选对象的值,并且当单击箭头按钮(和控制台日志)时,能够增加或减少状态的计数。 ,但我不确定将两者结合在一起的最佳方法(在数组中“ count”位置索引处显示项目?)

这是我的代码:

class DropdownMenu extends Component {
  state = {
    // Select options
    options: [
      { name: 'Item 1', label: 'Item 1' },
      { name: 'Item 2', label: 'Item 2' },
      { name: 'Item 3', label: 'Item 3' },
      { name: 'Item 4', label: 'Item 4' },
      { name: 'Item 5', label: 'Item 5' }
    ],
    value: 'select', // this should be the initial item ('Item 1')
    count: 0
  };

  change = e => {
    this.setState({ value: e.target.value }, console.log(this.state));
  };

  handleIncrement = () => {
    this.setState(
      {
        count: this.state.count + 1
      },
      () => {
        console.log(this.state);
      }
    );
  };

  handleDecrement = () => {
    this.setState(
      {
        count: this.state.count - 1
      },
      () => {
        console.log(this.state);
      }
    );
  };

  // Here I map over the options in state

  dropdown = () => (
    <div className="dropdown position-relative">
      <select onChange={this.change} value={this.state.value}>
        {this.state.options.map((option, index) => {
          return (
            <option key={index} name={option.name} value={option.name}>
              {option.label}
            </option>
          );
        })}
      </select>
      <div className="descend">
        <img className="icon" src={descendIcon} alt="" />
      </div>
    </div>
  );

  // I want to use these arrows to increment or decrement the selection on the drop down

  leftArrow = icon => (
    <button
      type="button"
      className="btn btn-2"
      onClick={this.handleIncrement}
    >
      <img className="icon" src={icon} alt="left arrow" />
    </button>
  );

  rightArrow = icon => (
    <button
      type="button"
      className="btn btn-2"
      onClick={this.handleDecrement}
    >
      <img className="icon" src={icon} alt="" />
    </button>
  );

  render() {
    return (
      <div className="flex flex-row">
        <div className="flex-grow">{this.dropdown()}</div>
        <div>
          {this.leftArrow(leftIcon)}
          {this.rightArrow(rightIcon)}
        </div>
      </div>
    );
  }
}

export default DropdownMenu;

在此示例中, this.state.count存储选定的options索引。 如果我们将this.state.count设置为select菜单的value那么当状态更新时, select将重新呈现并显示与更新后的计数匹配的选项。

现场演示: https : //codesandbox.io/s/38v727rrm

class DropdownMenu extends React.Component {
    state = {
        // Select options
        options: [
            { name: 'Item 1', label: 'Item 1' },
            { name: 'Item 2', label: 'Item 2' },
            { name: 'Item 3', label: 'Item 3' },
            { name: 'Item 4', label: 'Item 4' },
            { name: 'Item 5', label: 'Item 5' }
        ],
        count: 0
    };
    change = e => {
        this.setState({ count: Number(e.target.value) });
    };
    handleIncrement = () => {
        const c = this.state.count;
        const len = this.state.options.length - 1;
        let count = (c + 1 > len) ? c : c + 1;
        this.setState({ count });
    };
    handleDecrement = () => {
        const c = this.state.count;
        let count = (c - 1 < 0) ? c : c - 1;
        this.setState({ count });
    };
    dropdown = () => (
        <div className="dropdown position-relative">
            <select onChange={this.change} value={this.state.count}>
                {this.state.options.map((option, index) => (
                    <option key={index} name={option.name} value={index}>
                        {option.label}
                    </option>
                ))}
            </select>
            <div className="descend">
                <img className="icon" src="" alt="" />
            </div>
        </div>
    );
    leftArrow = icon => (
        <button
            type="button"
            className="btn btn-2"
            onClick={this.handleDecrement}
            >
            <img className="icon" src={icon} alt="left arrow" />
        </button>
    );
    rightArrow = icon => (
        <button
            type="button"
            className="btn btn-2"
            onClick={this.handleIncrement}
            >
            <img className="icon" src={icon} alt="right arrow" />
        </button>
    );    
    render() {
        return (
            <div className="flex flex-row">
                <div className="flex-grow">{this.dropdown()}</div>
                <div>
                    {this.leftArrow('leftIcon')}
                    {this.rightArrow('rightIcon')}
                </div>
            </div>
        );
    }
}

不要在您的状态下存储countvalue ,因为那样您将有两个选择真实性的来源。 只需存储count ,然后在您将获得value任何地方,获取options[count]

好的,我想念您的问题,所以您可以使用约瑟夫(Joseph)描述的逻辑来做到这一点。 使用options [index]获得价值,并始终更新索引

外观: https//codesandbox.io/s/zpwvjxjol

看一下React建议的处理setState的方法

由于React可以批量调用setState以获得更好的性能,所以您不能仅仅依靠this.state.count来作为更新状态的起点。 相反,您需要调用传递prevState作为参数之一的setState并使用prevState.count + 1

暂无
暂无

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

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