【问题标题】:How to toggle a button in React list?如何切换 React 列表中的按钮?
【发布时间】:2020-07-12 16:01:40
【问题描述】:

我渲染了一个 React 列表,每个列表项中都有一个编辑按钮。我想切换以从数据切换到输入表单并返回。类似于本文中的这个应用程序:https://medium.com/the-andela-way/handling-user-input-in-react-crud-1396e51a70bf。您可以通过以下方式查看演示:https://codesandbox.io/s/fragrant-tree-0t13x

这是我的 React 组件显示列表的地方:

import React, { Component } from "react";
import PriceBox from "../SinglePricebox/index";
// import SecurityForm from "../SecurityForm/index";
import AddPriceForm from "../AddPriceForm/index";
// import { uuid } from "uuidv4";

export default class PriceForm extends Component {
  constructor(props) {
    super(props);

    this.state = {
      priceArr: this.props.pricelist,
      // newPriceArr: this.props.updatePrice,
      showPricePopup: false,
      addPricePopup: false,
      isToggleOn: true,
      date: props.date || "",
      number: props.number || ""
    };
  }

  updateInput = ({ target: { name, value } }) =>
  this.setState({ [name]: value });

  togglePopup = () => {
    this.setState(prevState => ({
      showPopup: !prevState.showPopup 
    }));
  };

  togglePricePopup = () => {
    this.setState(prevState => ({
      showPricePopup: !prevState.showPricePopup
    }));
  };

  addPricePopup = () => {
    this.setState(prevState => ({
      addPricePopup: !prevState.addPricePopup
    }));
  };

    /* adds a new price to the list */
    addPrice = newPrice => {
      this.setState(prevState => ({
        addPricePopup: !prevState.addPricePopup,
        // spreads out the previous list and adds the new price with a unique id
        priceArr: [...prevState.priceArr, { ...newPrice }]
      }));
    };

    // handlePriceSubmission = () => {
    //   const { updatePrice } = this.props;

    //   this.addPricePopup();

    //   updatePrice(priceArr);
    // };

    toggleItemEditing = (index) => {
      this.setState(prevState => ({
        priceArr: prevState.priceArr.map(priceItem => {

              // isToggleOn: !state.isToggleOn;

        })
      }));
    };

    // toggleItemEditing = index => {
    //   this.setState({
    //     items: this.state.items.map((item, itemIndex) => {
    //       if (itemIndex === index) {
    //         return {
    //           ...item,
    //           isEditing: !item.isEditing
    //         }
    //       }
    //       return item;
    //     })
    //   });
    // };


  render() {
    // const { updatePrice } = this.props;

    return (
      <div className="popup">
        <div className="popup-inner">
          <div className="price-form">
            <h2>Prices</h2>
            <div className="scroll-box">
            {this.state.priceArr.map((props) => (
              <PriceBox
                {...props}
                key={props.date}
                // toggleItemEditing={this.toggleItemEditing()}
                onChange={this.handleItemUpdate}
              />
            ))}
            </div>
            <div className="buttons-box flex-content-between">
              <button
                type="button"
                onClick={this.addPricePopup}
                className="btn add-button">Add +</button>
                {this.state.addPricePopup && (
                      <AddPriceForm
                        addPrice={this.addPrice}
                        cancelPopup={this.addPricePopup}
                      />
                    )}
              <div className="add-btns">
              <button
                type="button"
                onClick={() => this.props.closeUpdatePopup()}
                className="btn cancel-button"
              >
                Close
              </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

上面组件里面的列表是:

<div className="scroll-box">
            {this.state.priceArr.map((props) => (
              <PriceBox
                {...props}
                key={props.date}
                // toggleItemEditing={this.toggleItemEditing()}
                onChange={this.handleItemUpdate}
              />
            ))}
            </div>

这是单个列表项:

import React, { Component } from "react";

export default class SinglePricebox extends Component {
  state = {
    showPopup: false, //don't show popup
    todaydate: this.props.date
  };

  /* toggle and close popup edit form window */
  togglePopup = () => {
    this.setState(prevState => ({
      showPopup: !prevState.showPopup
    }));
  };


  toggleEditPriceSubmission = getPriceIndex => {
      const { toggleItemEditing, date } = this.props;

      // toggle the pop up (close)
      // this.showPopup();

      toggleItemEditing({ ...getPriceIndex, date });
      console.log("date?", date);
    };

      /* handles edit current security form submissions */
  // handleEditSecuritySubmission = editSecurity => {
  //   const { editCurrentSecurity, id } = this.props;

  //   // toggle the pop up (close)
  //   this.togglePopup();

  //   // sends the editSecurity fields (name, isin, country) + id back to
  //   // App's "this.editCurrentSecurity"
  //   editCurrentSecurity({ ...editSecurity, id });
  // };

  render() {
    return (
      <div className="pricebox">
        <article className="pricetable">
        {this.toggleEditPriceSubmission
              ? "editing" : "not editing"}
          <table>
            <tbody>
              <tr>
                <td className="date-width">{this.props.date}</td>
                <td className="price-width">{this.props.number}</td>
                <td className="editing-btn">
                  <button
                    type="button"
                    className="edit-btn"
                    onClick={this.toggleEditPriceSubmission}
                  >
                    {this.toggleEditPriceSubmission ? "Save" : "Edit"}
                  </button>
                </td>
                <td>
                  <button
                    type="button"
                    className="delete-btn">
                      X
                    </button>
                </td>
              </tr>
            </tbody>
          </table>
        </article>
      </div>
    );
  }
}

我整个下午都在努力切换每个列表项中的编辑按钮。我试图获取每个列表项的键,即this.prop.date

您可以在 CodeSandBox 中查看我的详细代码:https://codesandbox.io/s/github/kikidesignnet/caissa

【问题讨论】:

  • 您好,您喜欢使用简单的表单而不是模态框?
  • ??我正在尝试创建一个切换功能来在表单和文本框之间切换
  • @KristinaBressler 你能提供一个minimal reproducible example 可能有很大帮助吗?

标签: javascript reactjs


【解决方案1】:

我将创建一个组件,它将列表项作为表单处理并像 SecurityForm 一样更新它。

 {this.state.priceArr.map((props) => {
     if(props) {
       return <PriceListForm methodToUpdate {...props} />
     }else {
       retun (
         <PriceBox
            {...props}
            key={props.date}
            // toggleItemEditing={this.toggleItemEditing()}
            onChange={this.handleItemUpdate}
          />
       );
     }
 })}

并使PriceListForm 看起来像PriceBox,但使用输入来捕获新数据。这样,您将拥有两个逻辑不太复杂的不同组件,而不是拥有一个具有复杂验证的大型组件来检查您是否会显示输入。

【讨论】:

    【解决方案2】:

    创建一个名为Edit 的函数来更新状态

    Edit = (id) => {
      this.setState({edit: !this.state.edit, id})
    }
    

    而不是那个

     <td className="country-width">{this.props.country}</td>
    

    做类似的事情

     <td className="country-width">{this.state.edit ? <input type="text" value={this.props.country} onChange={() => UPDATE_THE_CONTENT}/> : this.props.isin}</td>
    

    并调用编辑按钮的编辑函数 onclick 并将 td 的 ID 作为参数传递以更新它。 注意:默认情况下,编辑状态的值是 false/null。 您可以使用 onChange 更新该框或其他一些技术,例如创建一个按钮并使用它来更新它。 希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-17
      • 2022-11-10
      • 1970-01-01
      • 2020-09-29
      • 2018-01-14
      • 1970-01-01
      • 1970-01-01
      • 2021-11-28
      相关资源
      最近更新 更多