检查复选框

时间:2017-11-12 18:35:17

标签: javascript reactjs

我正在制作这个递归列表视图,如果切换父复选框,我试图显示/隐藏子组件。我在这里做错了,我不能再让它工作了。问题似乎与输入标记中onClick()函数的参数有关。我是React的新手,无法找到解决这个问题的方法。我可以帮忙解决一下这个问题吗?

export default class MyList extends Component {
      constructor(props) {
        super(props);
        this.state = {
          visible: true
        };
      }

      toggle = () => {
        this.setState(
          {visible: !this.state.visible}
        );
      };

      render() {
        var style;
        if (!this.state.visible) {
          style = {display: "none"};
        }

        var node = this.props.data;
        return(
          <div>
          <ul style={style}>
          {
            Object.keys(this.props.data).map(function(key){
            return (
                <li key={key}><input type="checkbox" onClick={MyList.toggle}/>
                  <label>{key}</label> :
                  {typeof node[key] === 'object' ? <MyList data = {node[key]} /> : node[key]}
                </li>
              );
            })
          }
          </ul>
          </div>
        );
      }
}

1 个答案:

答案 0 :(得分:1)

我不确定你到底要做什么 正如你在我们的评论中所看到的那样,我试图理解,但我仍然没有得到这个想法 从来没有那么简单,只是为了回答你的问题,并指出你正确的方向,你的问题是这一行:

onClick={MyList.toggle}

toggle是一种属于类的实例的方法,它不是静态成员,因此您必须在实例的上下文中调用它。 /> diong的一种方法是使用this作为当前实例的引用。问题是您在.map的{​​{1}}内使用匿名函数,Object.keys不再引用该实例。
为了确保this是类实例的引用,您可以使用箭头函数,该函数使用this的词汇上下文。

this

或者做旧的和丑陋的风格&#34;在函数的顶行使用{Object.keys(this.props.data).map(key => { return ( <li key={key}> <input type="checkbox" onClick={this.toggle} /> ... 。 (我更喜欢第二种选择) 顺便说一句,您将var that = this对象放在style元素上,这意味着一次点击后将隐藏整个ul。不确定这是你的意图。

以下是您的代码的运行示例:

&#13;
&#13;
ul
&#13;
class MyList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      visible: true
    };
  }

  toggle = () => {
    this.setState({ visible: !this.state.visible });
  };

  render() {
    var style;
    if (!this.state.visible) {
      style = { display: "none" };
    }

    var node = this.props.data;
    return (
      <div>
        <ul style={style}>
          {Object.keys(this.props.data).map(key => {
            return (
              <li key={key}>
                <input type="checkbox" onClick={this.toggle} />
                <label>{key}</label> :
                {typeof node[key] === "object" ? (
                  <MyList data={node[key]} />
                ) : (
                  node[key]
                )}
              </li>
            );
          })}
        </ul>
      </div>
    );
  }
}

ReactDOM.render(<MyList data={[1, 2, 3]} />, document.getElementById("root"));
&#13;
&#13;
&#13;

修改
作为评论的后续内容:

  

尝试制作类似this Fiddle的内容,而不是   复选框,但我无法折叠列表。

以下是带有复选框输入的链接中的代码版本:

&#13;
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
&#13;
class TreeNode extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      visible: true
    };
  }

  toggle = () => {
    this.setState({ visible: !this.state.visible });
  };

  render() {
    var childNodes;
    var classObj;

    if (this.props.node.childNodes != null) {
      childNodes = this.props.node.childNodes.map(function(node, index) {
        return (
          <li key={index}>
            <TreeNode node={node} />
          </li>
        );
      });

      classObj = {
        togglable: true,
        "togglable-down": this.state.visible,
        "togglable-up": !this.state.visible
      };
    }

    var style;
    if (!this.state.visible) {
      style = { display: "none" };
    }

    return (
      <div>
        <h5 className={classNames(classObj)}>
          <input
            checked={this.state.visible}
            type="checkbox"
            onClick={this.toggle}
          />
          {this.props.node.title}
        </h5>
        <ul style={style}>{childNodes}</ul>
      </div>
    );
  }
}

var tree = {
  title: "howdy",
  childNodes: [
    { title: "bobby" },
    {
      title: "suzie",
      childNodes: [
        {
          title: "puppy",
          childNodes: [{ title: "dog house" }]
        },
        { title: "cherry tree" }
      ]
    }
  ]
};

ReactDOM.render(<TreeNode node={tree} />, document.getElementById("root"));
&#13;
body {
  font-family: "Helvetica Neue";
}

h3 {
  color: #BF616A;
}

.togglable {
  color: #D78770;
  cursor: pointer;
}

.togglable-down::after,
.togglable-up::after {
  font-size: 8px;
  margin-left: 0.5em;
}

.togglable-down::after {
  content: "▼";
  display: inline-block;
}

.togglable-up::after {
  content: "▶";
  display: inline-block;
}
&#13;
&#13;
&#13;