在表格中查找您单击的行

IT技术 reactjs
2021-05-11 12:55:01

我想找到在表中单击的行的 id。例如,我搜索了一本名为“Mastery”的书,有 2 本书具有相同的书名但作者不同。这些书正确显示在表中。我想要做的是当我点击表格中的一本书时,它应该打开一个带有输入框中书籍详细信息的模式,但是当我点击任何一本书时,模式会弹出其中一个的详细信息图书。

当我输入搜索词 ('Mastery') 时,我得到两个建议,这是预期的行为。 在此处输入图片说明

当我点击建议的搜索词('Mastery')并点击回车或搜索按钮时。具有该标题('Mastery')的所有书籍都填充在表中。也是预期的行为。 在此处输入图片说明

现在,当我点击标题为“Mastery”的书的第一个实例时,这就是我在模态中得到的。 在此处输入图片说明

当我单击第二个实例时。我明白了。 在此处输入图片说明

你意识到它是在模态中显示的同一本书。

预期行为: 我希望能够点击表格中的一本书,并且该行中的书显示在模态中。

import React, { Component } from 'react';
import './Update.css';
// import Pace from 'react-pace-progress';

//CHILD COMPONENTS
import Search from '../../Search/Search';
import Modal from './Modal/Modal';

const Table = ({ data, openBookDetails }) => (
    <table className="table table-hover">
        <thead>
            <tr className="table-primary">
                <th scope="col">Title</th>
                <th scope="col">Author</th>
                <th scope="col">ISBN</th>
                <th scope="col">No. Of Copies</th>
            </tr>
        </thead>
        <tbody>
            {data.map(row => 
                <TableRow key={row._id} row={row} openBookDetails={openBookDetails}/>
            )}
            {/* Remove key={row.id} inside TableRow because it is not used to set the data in the table */}
        </tbody>
    </table>
)

const TableRow = ({ row, openBookDetails }) => (
     <tr className="table-light" onClick={openBookDetails}>
        <th scope="row" >{row.title}</th>
        <td >{row.author}</td>
        <td >{row.isbn}</td>
        <td >24</td>
    </tr>
)


class Update extends Component{
    constructor(props) {
        super(props);

        this.state = {
            value: '',
            suggestions: [],
            setOfAllBooks: [],
            searchedBooks: [],
            isBookDetailsOpen: false,
            searchForEmpty: true,
            isDataFetching: true,

            title: '',
            author: '',
            isbn: ''
        };
    }

    setTableData = (searchedBook) => {
        this.setState({searchedBooks: searchedBook});
    }

    openBookDetails = () => {
        this.setState({ isBookDetailsOpen: true});

        console.log(this.state.searchedBooks);

        this.setState({ title: this.state.searchedBooks.title});
        this.setState({ author: this.state.searchedBooks.author});
        this.setState({ isbn: this.state.searchedBooks.isbn});
    }

    closeBookDetails = () => {
        this.setState({ isBookDetailsOpen: false});
    }

    changeIsSearchForEmpty = () => {
        this.setState({ searchForEmpty: !this.state.searchForEmpty });
    }

    changeIsDataFetching = () => {
        this.setState({isDataFetching: !this.state.isDataFetching})
    }

    render(){

        const showHideAlert = this.state.searchForEmpty ? 'alert alert-danger d-none' : 'alert alert-danger d-block';
        // const showHideProgress1 = this.state.isDataFetching ? 'progress' : 'progress display-none';
        const showHideProgress =  this.state.isDataFetching ? 'progress progress-bar progress-bar-striped bg-success progress-bar-animated d-block' : 'progress-bar progress-bar-striped progress-bar-animated d-none';

        const style= {
            width: "100%",
            height: "8px"
        }

        return(
            <div>
                {/* Uninstall react-pace-progress if not going to be used */}
                {/* {this.state.isDataFetching ? <Pace color="#27ae60" height="0.5px"/> : null} */}
                <div style={style}>
                    <div class={showHideProgress} role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style={style}></div>
                </div>
                <div className={showHideAlert}>
                    <strong>Sorry!</strong> You have to type in a search word/phrase.
                </div>

                <div className='px-3 pt-3'>      


                    <Search 
                        state={this.state} 
                        setTableData={this.setTableData} 
                        changeIsSearchForEmpty={this.changeIsSearchForEmpty}
                        changeIsDataFetching={this.changeIsDataFetching} />
                    <Table 
                        data={this.state.searchedBooks} 
                        openBookDetails={this.openBookDetails} />
                    <Modal 
                        data={this.state.searchedBooks} 
                        isBookDetailsOpen={this.state.isBookDetailsOpen} 
                        closeBookDetails={this.closeBookDetails}
                        updateBookDetails={this.updateBookDetails} 
                        grabTitle={this.grabTitle}
                        grabAuthor={this.grabAuthor}
                        grabISBN={this.grabISBN}
                        state={this.state} />
                </div>
            </div>
        );
    }
}

export default Update;
2个回答

您将需要trTableRow组件元素上使用某种 ID 或索引您无需在代码中添加任何额外的 react 元素即可实现目标,但您的onClick函数回调必须能够获取实际值。

如果你看看下面的代码:

import React from "react";
import ReactDOM from "react-dom";

const data = [
  { id: "one", firstname: "john", lastname: "smith" },
  { id: "foo", firstname: "peter", lastname: "parker" }
];

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      clicked_id: null
    };
  }

  onClick = event => {
    const id = event.currentTarget.getAttribute("data-rowid");
    console.log(id);
    this.setState({ clicked_id: id });
  };

  render() {
    return (
      <div>
        <div>Clicked ID: {this.state.clicked_id}</div>
        <table>
          <thead>
            <tr>
              <th>ID</th>
              <th>First Name</th>
              <th>Last Name</th>
            </tr>
          </thead>
          <tbody>
            {data.map(e => (
              <tr key={e.id} data-rowid={e.id} onClick={this.onClick}>
                <td>{e.id}</td>
                <td>{e.firstname}</td>
                <td>{e.lastname}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

您可以看到tr实际上有一个data-rowid元素,稍后该onClick方法会使用元素来提取值。你可以使用其他标签,我只是为自己选择了那个。

编辑添加:

如果你想看看上面工作的代码,看看这个代码和框链接:

https://codesandbox.io/s/4368l97lqx

第二次编辑:

您可以重构您的TableRow组件以openBookDetails使用您想要的参数调用prop 函数:

class TableRow extends React.Component {
  handleClick = (event) => {
    event.stopPropagation();
    const { row, openBookDetails } = this.props;
    openBookDetails(row._id);
  };

  render() {
    const { row } = this.props;
    return (
       <tr className="table-light" onClick={this.handleClick}>
        <th scope="row">{row.title}</th>
        <td>{row.author}</td>
        <td>{row.isbn}</td>
        <td>24</td>
      </tr>
    );
  }
}

根据您在下面突出显示的代码:

<tbody>
            {data.map(row => 
                <TableRow key={row._id} row={row} openBookDetails={openBookDetails}/>
            )}
            {/* Remove key={row.id} inside TableRow because it is not used to set the data in the table */}
</tbody>

我认为您需要将行值传递给 openBookDetails,例如:

<TableRow key={row._id} row={row} openBookDetails={openBookDetails(row)}/> 

并相应地使用 openBookDetails 函数中发送的行值