在组件上只对onClick工作一次

时间:2018-05-19 11:12:50

标签: reactjs onclick

您好我正在尝试建立一个论坛网站。我有简单的类别和评论。我有一个显示文本框的按钮,用于输入类别的注释,但是当我单击按钮时,它会打开每个类别的文本框。我只想要一个文本框。这是我到目前为止的代码。任何帮助,将不胜感激。感谢

state = { showing: true };

renderLists(categories) {
  const { showing } = this.state;

  if (categories == null) return <div />;
  return (
    <ul className="ul">
      {categories.map(category => {
        return (
          <li id={category._id} className="categories" key={category._id}>
            {category.name}

            <Posts categ={category._id} />
            <button
              className="label"
              onClick={() => this.setState({ showing: !showing })}
            >
              Add Comment
            </button>
            {showing ? (
              <div>
                <form method="post" action="/post/create-posts">
                  <input type="text" name="body" />

                  <input type="hidden" name="cat" value={category._id} />
                  <input type="submit" value="Submit" />
                </form>
              </div>
            ) : null}
          </li>
        );
      })}
    </ul>
  );
}

render() {
  return (
    <div>
      <main className="categories">
        {this.renderLists(this.state.category)}
      </main>
    </div>
  );
}

2 个答案:

答案 0 :(得分:0)

由于您使用单个状态值控制表单的呈现,因此每个项目的表单都会在状态值更改时呈现表单。

您应该在州上设置一个唯一值,以便每次都显示单个表单。

将当前活动的项目ID保存到状态并检查该项目是否处于活动状态可以是一个简单的解决方案。这也确保了只有单个表格才能生效。如果需要启用多个表单,可以更改下面的代码以保存一组id并检查id是否存在于数组中。此实现还要求您在第二次单击时从数组中删除id以删除该项目的表单。

<强>示例

state = { showing: ''};

renderLists(categories) {
  const { showing } = this.state;

  if (categories == null) return <div />;
  return (
    <ul className="ul">
      {categories.map(category => {
        return (
          <li id={category._id} className="categories" key={category._id}>
            {category.name}

            <Posts categ={category._id} />
            <button
              className="label"
              {/* Save item's id to state */}
              onClick={() => this.setState({ showing: category._id })}
            >
              Add Comment
            </button>
            {/* check item's id */}
            {(showing === category._id) ? (
              <div>
                <form method="post" action="/post/create-posts">
                  <input type="text" name="body" />

                  <input type="hidden" name="cat" value={category._id} />
                  <input type="submit" value="Submit" />
                </form>
              </div>
            ) : null}
          </li>
        );
      })}
    </ul>
  );
}

答案 1 :(得分:0)

您可以为每个类别设置动态状态。我在下面做了。最初它不在州。单击该按钮,它将使用新键(例如categoryName)将状态更新为true。我把它修好为切换。如果所需的密钥为true,那么它将变为false。

item.state = { showing: true };

renderLists(categories) {
  const { showing } = this.state;

  if (categories == null) return <div />;
  return (
    <ul className="ul">
      {categories.map(category => {
        let categoryName = category.name  // get the categoryName in variable

        return (
          <li id={category._id} className="categories" key={category._id}>
            {category.name}

            <Posts categ={category._id} />
            //You can also access the object values by using bracket ([]) notation. You can set the dynamic state with unique key, may be we use name as key here
            <button
              className="label"
              onClick={() => {(this.state[categoryName] != undefined) ? (this.state[categoryName] ? this.setState({ [categoryName]: false }) : this.setState({ [categoryName]: true })) : this.setState({ [categoryName]: true })} } 
            >
              Add Comment
            </button>
            {this.state[categoryName] ? (
              <div>
                <form method="post" action="/post/create-posts">
                  <input type="text" name="body" />

                  <input type="hidden" name="cat" value={category._id} />
                  <input type="submit" value="Submit" />
                </form>
              </div>
            ) : null}
          </li>
        );
      })}
    </ul>
  );
}

render() {
  return (
    <div>
      <main className="categories">
        {this.renderLists(this.state.category)}
      </main>
    </div>
  );
}