在React

时间:2017-01-18 05:15:21

标签: javascript reactjs

背景

我在写作的反应应用中遇到了问题。我一直试图从表中删除一行,但我一直在

  

setState未定义

所以基本上我就是这样设置的。

此函数将从表中删除行。    我没有测试过这个因为我一直得到

  

未定义的错误setState

function removeRow(id) {
  this.setState(state => {
     state.tableData.splice(id, 1);
     return {tableData: state.tableData};
   });
}

问题

tr点火时table如何正确删除onClick method state,以便render更改并table {{1}没有被删除的tr的话?

实施例

这是调用onClick的{​​{1}}方法。

removeRow()

这就是它们在一起的样子,

<td><a href="#" onClick={() => { removeRow(tableData[key].id) }}>Delete</a></td>

我还尝试将var requests = [ {"id":1, "title":"Request from Nancy","updated_at":"2015-08-15 12:27:01 -0600","created_at":"2015-08-12 08:27:01 -0600","status":"Denied"} ] class TableDisplay extends React.Component { constructor() { super(); this.state = { tableData: requests } } render() { const {tableData} = this.props; return ( <div className="table-wrapper"> <div><table className="table"> <tr className="separate"><td>Title</td><td>Status</td> <td>Created</td><td>Updated</td><td>Delete</td></tr> {Object.keys(tableData).map(function(key) { function removeRow(id) { this.setState(state => { state.tableData.splice(id, 1); return {tableData: state.tableData}; }); } return // removed extra code to make it easy to read. <td><a href="#" onClick={() => { removeRow(tableData[key].id) }}>Delete</a></td> </tr>; })} </table> </div> </div> ); } } 直接移到removeRow()下方constructor上方,但是当我这样做时,当onClick触发时,removeRow()会抛出错误,

  

removeRow未定义。

render()

4 个答案:

答案 0 :(得分:3)

您的组件存在一些问题,即您不会在remove函数中绑定上下文(因此setState未定义)。尝试这样的事情:

const TableRow = (props) => (
   <tr>
      <td>{props.title}</td>
      <td>{props.status}</td>
      <td>{props.updated_at}</td>
      <td>{props.created_at}</td>
      <td><a href="#" onClick={() => props.remove(props.index)}>Delete</a></td>
   </tr>
)

class TableDisplay extends React.Component {

   constructor() {
      super();
      this.state = {
         tableData: [{
            "id":1,
            "title":"Request from Nancy",
            "updated_at":"2015-08-15 12:27:01 -0600",
            "created_at":"2015-08-12 08:27:01 -0600",
            "status":"Denied"
         }]
      };
   }

   remove(index) {
      this.setState({
         tableData: this.state.tableData.filter((row, i) => i !== index)
      });
   }

   render() {
      return (
         <div className="table-wrapper">
            <div>
               <table className="table">
                  <tbody>
                     {
                        this.state.tableData.map((row, i) => {
                           return (
                              <TableRow
                                 title={row.title}
                                 id={row.id}
                                 updated_at={row.updated_at}
                                 created_at={row.created_at}
                                 status={row.status}
                                 remove={this.remove.bind(this)}
                                 index={i}
                                 key={i} />
                           );
                        })
                     }
                  </tbody>
               </table>
            </div>
         </div>
      );
   }
}

ReactDOM.render((
   <TableDisplay />
), document.getElementById("app"));

答案 1 :(得分:2)

这种情况失去了。

您可以将功能绑定到this

class TableDisplay extends React.Component {
constructor() {
    super();
    this.state = {
      tableData: requests
    }
  //ADD THIS LINE
  this.removeRow = this.removeRow.bind(this);
  }

// I have to remove "function" from the declaration or the app wont render from parse error.

   removeRow(id) {
         this.setState(state => {
            state.tableData.splice(id, 1);
            return {tableData: state.tableData};
        });
     }
 ......

<a href="#" onClick={() => { this.removeRow(tableData[key].id) }}

或者,如果您使用的是ES6 Stage 2 preset,则可以使用箭头功能

class TableDisplay extends React.Component {
constructor() {
    super();
    this.state = {
      tableData: requests
    }
  }

// I have to remove "function" from the declaration or the app wont render from parse error.

   removeRow = (id) => {
         this.setState(state => {
            state.tableData.splice(id, 1);
            return {tableData: state.tableData};
        });
     }
 ......

答案 2 :(得分:1)

当你在第二个解决方案中调用removeRow时,你需要像this.removeRow一样调用它,因为它在渲染函数之外。您还需要绑定它以便访问setState。为此,您可以使用箭头功能

class TableDisplay extends React.Component {
constructor() {
    super();
    this.state = {
      tableData: requests
    }
  }

// I have to remove "function" from the declaration or the app wont render from parse error.

   removeRow = (id) => {
         this.setState(state => {
            state.tableData.splice(id, 1);
            return {tableData: state.tableData};
        });
     }

  render() {
    const {tableData} = this.props;

    return (
      <div className="table-wrapper">
        <div><table className="table">
            <tr className="separate"><td>Title</td><td>Status</td>           
               <td>Created</td><td>Updated</td><td>Delete</td></tr>
     {Object.keys(tableData).map(function(key) {       

        return // removed extra code to make it easy to read.
        <td><a href="#" onClick={() => { this.removeRow(tableData[key].id) }}>Delete</a></td>
        </tr>;

        }.bind(this))}
           </table>
        </div>
      </div>
    );
  }
}

答案 3 :(得分:1)

**Put removeRow method above render() and give current scope reference as var that = this; **


     class TableDisplay extends React.Component {
      constructor() {
    super();
    this.state = {
      selectValue: 'all',
      tableData: requests
    }
    }

    removeRow() {
             this.setState(state => {
             state.tableData.splice(id, 1);
             return {tableData: state.tableData};
        });
     }

    render() {
    const {selectValue} = this.props;
    const {tableData} = this.props;
    var that = this;
     return (
      <div className="table-wrapper">
        <div><table className="table">
              <tr className="seperate"><td>Title</td><td>Status</td><td>Created</td><td>Updated</td><td>Delete</td></tr>
            {Object.keys(tableData).map(function(key) {  
        let styling = "bg-plain";
                let hidden = "hidden";
        let tds = document.querySelectorAll(".table td");
        let trs = document.querySelectorAll(".table tr");

        function showHiddenRows() {
        for (var i = 0; i < trs.length; i++) {
                trs[i].classList.remove("hidden");
            }
        }

        function setStyle() {
        if (tableData[key].status === "Approved") {
                    styling = "bg-success";
                    } else if (tableData[key].status === "Denied") {
                    styling = "bg-danger";
                }   
            for (var i = 0; i < tds.length; i++) {
                        if (tds[i].innerText === "Approved") {
                  tds[i].parentNode.setAttribute('class', 'bg-success')
                    } else if (tds[i].innerText === "Denied") {
                                    tds[i].parentNode.setAttribute('class', 'bg-danger')
                    }
            }
        }

        function filterTable(fa, fb) {
        for (var i = 0; i < tds.length; i++) {
                        if (tds[i].innerText === fa) {
                  tds[i].parentNode.setAttribute('class', 'hidden')
                    } else if (tds[i].innerText === fb) {
                                    tds[i].parentNode.setAttribute('class', 'hidden')
                    }
           }
        }



        if (selectValue === "all") {
                    showHiddenRows();
            setStyle(); 
        } else if (selectValue === "approved") {
             showHiddenRows();
           setStyle();      
           filterTable("Pending", "Denied");
            } else if (selectValue === "pending") {
            showHiddenRows();
            setStyle(); 
            filterTable("Approved", "Denied");
            } else if (selectValue === "denied") {
          showHiddenRows();
          setStyle();
          filterTable("Approved", "Pending");
        }

      {console.log(tableData[key].id)} 
        return <tr key={tableData[key].id} id={tableData[key].id} className={styling}>
        <td>{tableData[key].title}</td>
        <td>{tableData[key].status}</td>
        <td>{tableData[key].created_at.slice(0, 10)}</td>
        <td>{tableData[key].updated_at.slice(0, 10)}</td>
        <td><a href="#" onClick={() => { that.removeRow() }}>Delete</a></td>
        </tr>;

        })}
              </table>
            </div>
      </div>
    );
  }
}