React JS,单击“显示元素的下拉列表”

时间:2017-07-21 11:44:06

标签: javascript html reactjs

我的问题是关于尝试在单击span元素时显示静态下拉列表,但是我如何只显示单击元素的下拉列表(并关闭打开的下拉列表)而不添加任何新DOM。有人可以帮忙吗? 到目前为止我尝试的是。

const SubSubComponent = props => {
  let dropdown = () => {
    if (props.openDropDownFlag) {
      return (
        <ul style={{ listStyle: 'none', border: '1px     solid #000' }}>
          <li>User data </li>
          <li>Edit</li>
        </ul>
      );
    }
  };

  return (
    <div>
      <span onClick={props.clickHandler}>
        {props.name}
      </span>
      <div>
        {dropdown}
      </div>
    </div>
  );
};

const SubComponent = props => {
  let returnVal = props.list.length
    ? props.list.map((item, index) => {
        return (
          <SubSubComponent
            key={index}
            name={item}
            openDropDownFlag={props.openDropDownFlag}
            clickHandler={props.openDropDown}
          />
        );
      })
    : null;

  return (
    <div>
      {returnVal}
    </div>
  );
};

class Main extends React.Component {
  constructor() {
    super();
    this.state = {
      arrayList: ['Matt', 'Maxx', 'Newton'],
      openDropDownFlag: false,
    };
    this.openDropDown = this.openDropDown.bind(this);
  }
  openDropDown = () => {
    //code to show dropdown
    debugger;
    this.setState({
      openDropDownFlag: true,
    });
  };
  render() {
    return (
      <div>
        <SubComponent
          list={this.state.arrayList}
          openDropDown={this.openDropDown}
          openDropDownFlag={this.state.openDropDownFlag}
        />
      </div>
    );
  }
}
render(<Main />, document.getElementById('root'));

我在Code Sandbox

中尝试了相同的操作

1 个答案:

答案 0 :(得分:1)

使用您的沙箱,我制作了一个不涉及子组件的简化版本,每次点击一个范围时,它会更新状态以将开放下拉列表设置在范围下方,并且因为它只是跟踪&#39;打开&#39;列表,已打开的列表消失。

沙箱在这里:https://codesandbox.io/s/BLwl1y6j2

import React from 'react';
import { render } from 'react-dom';


class Main extends React.Component {

  constructor() {
    super();
    this.state = {
      arrayList: ['Matt', 'Maxx', 'Newton'],
      open: null
    };
  }

  openList = () => {
    return (
      <ul style={{ listStyle: 'none', border: '1px solid #000' }}>
        <li>User data </li>
        <li>Edit</li>
      </ul>
    );
  }

  openDropDown = (event) => {
    console.log(event.target.innerText);
    this.setState({
      open: event.target.innerText,
    });
  }

  render() {
    return (
      <div>
        {
          this.state.arrayList.map((name, index) => {
            return (<div key={`${name}-${index}`}>
            <span onClick={ this.openDropDown }>
              { name }
            </span>
              { name === this.state.open ? this.openList() : null }
          </div>);
          })
        }
      </div>
    );
  }
}
render(<Main />, document.getElementById('root'));

我以前写过这样的组件,根据我的经验,下拉列表实际上并不是一件容易的事。我有一个选择列表下拉列表,当其他下拉列表位于其附近时需要表现一致,这样当单击下拉列表时,展开的下拉列表视图将展开并浮动其他UI元素。同样,它必须防止在扩展时点击附近的其他下拉列表组件,并且当我点击屏幕上的任何其他位置时它必须恢复到非下拉模式。此外,它还必须处理单击以选择扩展列表本身上的项目。

要实现这些行为,需要对具有不同z索引的不可见绝对和相对定位div元素进行一些分层,以收集onClick事件并对UI中的不同单击操作做出反应。总的来说,这是一组非常复杂的互动。