- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
好吧,我是 React 新手,需要帮助读取/引用 HTML 元素数据属性,甚至 HTML 标记中的内容 - 通常使用纯 JS(这就是我在 React 应用程序中所做的)我读像这样:
const postRow = document.getElementById(tableRowId);
;
const author = postRow.getElementsByTagName('td')[0].getAttribute('data-fieldvalue');
const title = postRow.getElementsByTagName('td')[1].getAttribute('data-fieldvalue');
const description = postRow.getElementsByTagName('td')[2].getAttribute('data-fieldvalue');
我有一个名为 Table 的功能组件,我这样使用:
<Table
headers={this.state.postsHeaders}
rows={this.state.posts}
editable={this.state.editable}
deletable={this.state.deletable}
onUpdateIconClicked={this.toggleUpdatePostModalView}
onDeleteIconClicked={this.toggleDeletePostModalView}
/>
其中 rows 属性是我使用 axios 检索的数据。我的表生成了包含多个 tr > td
行的 find 。我为每一行都有一个“编辑”CTA,单击它会打开一个模式,在其中传递要为每一行编辑的数据。 CTA 的 Onclick 调用这个函数,效果很好:
toggleUpdatePostModalView = (postId, tableRowId) => {
// toggle the confirm delete post view
let showUpdatePostModal = !this.state.showUpdatePostModal;
// when postId and tableRowId are both null that means
// that the view delete confirm modal must remain not
// visible (closed) so have to override the toggle
if (postId === null && tableRowId === null) {
showUpdatePostModal = false;
}
const postRow = document.getElementById(tableRowId);
;
const author = postRow.getElementsByTagName('td')[0].getAttribute('data-fieldvalue');
const title = postRow.getElementsByTagName('td')[1].getAttribute('data-fieldvalue');
const description = postRow.getElementsByTagName('td')[2].getAttribute('data-fieldvalue');
// dont get the elements directly like above https://reactjs.org/docs/refs-and-the-dom.html
this.setState({
...this.state,
showUpdatePostModal: showUpdatePostModal,
postToUpdate: {
postId: postId,
tableRowId: tableRowId,
author: author,
title: title,
description: description
}
});
}
有人指出的问题是我不应该使用 JS 方式获取数据(getElementById
和 getElementsByTagName
函数,因为虚拟 DOM 和真实 DOM 同步所以我被指向 https://reactjs.org/docs/refs-and-the-dom.html 但如果我的 tr
本身是一个组件,这似乎可以工作,但事实上,它只是我的 Table 渲染函数中的 HTML,如下所示:
const table = (props) => {
// the following code creates an array from props.header object
// that is an indexed array (0, 1, ..., n) and each value
// contains the key properties that compose object props.header,
// and so, even though in .map() the parameter says 'key'
// this is misleading because in reality it is the VALUE
// (since the key of the array is 0 or 1 or n) but it is called
// 'key' because it is the key in the props.headers object that we
// need to get the info for (.map(function(currentValue, index, arr))
const headersArray = Object.keys(props.headers);
const tableHeaders = headersArray.map(key => {
return <th key={key}>{props.headers[key]}</th>;
});
const editHeader = props.editable === true ? <th key="edit">Edit</th> : null;
const deleteHeader = props.deletable === true ? <th key="delete">Delete</th> : null;
let tableRows = null;
if (props.rows) {
tableRows = props.rows.map((row, key) => {
return (
<tr id={`tr-${key}`} key={key}>
{/* inner loop to dynamically generate the <td>
depending on how many headers there are since
each header corresponds to a key or column in
the table */}
{headersArray.map(tdKey => {
return <td key={tdKey} data-fieldname={tdKey} data-fieldvalue={row[tdKey]} >{row[tdKey]}</td>
})}
{props.editable === true ? <td key="edit"><PencilIcon onClick={() => props.onUpdateIconClicked(row.postId, `tr-${key}`)} /></td> : null}
{props.deletable === true ? <td className="delete-icon-container" key="delete"><TrashIcon onClick={() => props.onDeleteIconClicked(row.postId, `tr-${key}`)} /></td> : null}
</tr>
);
});
}
return (
<table className="table is-striped">
<thead>
<tr>
{tableHeaders}
{editHeader}
{deleteHeader}
</tr>
</thead>
<tbody>
{tableRows}
</tbody>
</table>
);
}
我还了解到这些引用不应该经常使用 - 那么如果我有一个包含 100 行的表怎么办? 200?我不知道如何继续并以 React 方式执行此操作...任何人都可以帮忙吗?
最佳答案
引用号是NOT 一个适合在这里使用的工具。
相反,你应该这样做lifting state up (很多)。
为了做到这一点,我建议
<Header />
内的较小部分(例如 <Row />
、 <App />
等)和一个单独的 <EditDialog />
/<DeleteDialog />
编辑/删除行数据的组件)-较小的组件更易于维护和故障排除id
)存储在父组件 ( <Table />
) 中,并将与表行相对应的数据条目作为参数传递给 <Row />
组件onEdit()
和onDelete()
事件处理程序作为<Row />
的 Prop 组件并将其附加到 onClick()
编辑/删除按钮的处理程序onEdit()
、 onDelete()
)绑定(bind)到父级中将触发编辑/删除对话框的回调<Table />
的状态相应地。这是上述内容的完整演示(我使用 MaterialUI 进行样式设置,以免使用大量 CSS 使演示负担过重,您可以继续使用自定义组件,希望这不会成为我的示例您不太清楚):
const { useState } = React,
{ render } = ReactDOM,
{ TableContainer, Table, TableHead, TableBody, TableRow, TableCell, IconButton, Dialog, DialogTitle, DialogContent, DialogContentText, Button, TextField, FormGroup } = MaterialUI
const srcData = [{id:0, author: 'Author1', title: 'Post 1', description: 'Some description'},{id:1, author: 'Author2', title: 'Post 2', description: 'Some other description'},{id:2, author: 'Author3', title: 'Post 3', description: 'Something else'}],
dataFields = [{id: 0, title: 'Author', key: 'author'},{id: 1, title: 'Title', key: 'title'},{id:2, title: 'Description', key: 'description'}]
const EditButton = ({handleClick}) => (
<IconButton onClick={handleClick} >
<i className="material-icons">create</i>
</IconButton>
)
const DeleteButton = ({handleClick}) => (
<IconButton onClick={handleClick} >
<i className="material-icons">delete</i>
</IconButton>
)
const DeleteDialog = ({isOpen, onDialogClose, onConfirmDelete, recordId}) => (
<Dialog open={isOpen} onClose={onDialogClose} >
<DialogTitle>Delete record</DialogTitle>
<DialogContent>
<DialogContentText>Are you sure you want to delete this record?</DialogContentText>
<FormGroup>
<Button onClick={() => onConfirmDelete(recordId)}>Yes</Button>
<Button onClick={onDialogClose}>No</Button>
</FormGroup>
</DialogContent>
</Dialog>
)
const EditDialog = ({isOpen, onDialogClose, onSubmitEdit, recordData, fields}) => {
const [data, setData] = useState(),
handleEdit = (key,value) => setData({...data, [key]:value})
return (
<Dialog open={isOpen} onClose={onDialogClose} >
<DialogTitle>Edit record</DialogTitle>
<DialogContent>
<FormGroup>
{
fields.map(({key,title}) => (
<TextField
key={key}
defaultValue={recordData[key]}
label={title}
onChange={({target:{value}}) => handleEdit(key,value)}
/>
))
}
</FormGroup>
<FormGroup>
<Button onClick={() => onSubmitEdit({...recordData,...data})}>Submit</Button>
<Button onClick={() => onDialogClose()}>Cancel</Button>
</FormGroup>
</DialogContent>
</Dialog>
)
}
const Header = ({columnTitles}) => (
<TableHead>
<TableRow>
{columnTitles.map(({title,id}) => <TableCell key={id}>{title}</TableCell>)}
<TableCell>Action</TableCell>
</TableRow>
</TableHead>
)
const Row = ({rowData, columns, onEdit, onDelete}) => (
<TableRow>
{columns.map(({key}, i) => <TableCell key={i}>{rowData[key]}</TableCell>)}
<TableCell>
<EditButton handleClick={() => onEdit(rowData.id)} />
<DeleteButton handleClick={() => onDelete(rowData.id)} />
</TableCell>
</TableRow>
)
const App = ({data,fields}) => {
const [tableData, setTableData] = useState(data),
[dataFields, setDataFields] = useState(fields),
[deleteDialogOn, setDeleteDialogOn] = useState(false),
[editDialogOn, setEditDialogOn] = useState(false),
[recordIdToDelete, setRecordIdToDelete] = useState(),
[recordIdToEdit, setRecordIdToEdit] = useState(),
onEditDialogOpen = (id) => (setRecordIdToEdit(id),setEditDialogOn(true)),
onDeleteDialogOpen = (id) => (setRecordIdToDelete(id), setDeleteDialogOn(true)),
handleEdit = (data) => {
setEditDialogOn(false)
const tableDataCopy = [...tableData],
editedItemIdx = tableDataCopy.findIndex(({id}) => id == data.id)
tableDataCopy.splice(editedItemIdx,1,data)
setTableData(tableDataCopy)
},
handleDelete = (idRecordToDelete) => {
setDeleteDialogOn(false)
const tableDataCopy = [...tableData]
setTableData(tableDataCopy.filter(({id}) => id!=recordIdToDelete))
}
return (
<div>
<DeleteDialog
isOpen={deleteDialogOn}
onDialogClose={() => setDeleteDialogOn(false)}
onConfirmDelete={handleDelete}
recordId={recordIdToDelete}
/>
<EditDialog
isOpen={editDialogOn}
onDialogClose={() => setEditDialogOn(false)}
onSubmitEdit={handleEdit}
recordData={tableData.find(({id}) => id==recordIdToEdit)||{}}
fields={dataFields}
/>
<TableContainer>
<Table>
<Header columnTitles={dataFields} />
<TableBody>
{
tableData.map(data => (
<Row
key={data.id}
rowData={data}
columns={dataFields}
onEdit={onEditDialogOpen}
onDelete={onDeleteDialogOpen}
/>
))
}
</TableBody>
</Table>
</TableContainer>
</div>
)
}
render (
<App data={srcData} fields={dataFields} />,
document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><script src="https://unpkg.com/@material-ui/core@latest/umd/material-ui.development.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.1/axios.min.js"></script><link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"><div id="root"></div>
关于javascript - 可编辑 react 表: pass data between components,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60419278/
我有一台 MySQL 服务器和一台 PostgreSQL 服务器。 需要从多个表中复制或重新插入一组数据 MySQL 流式传输/同步到 PostgreSQL 表。 这种复制可以基于时间(Sync)或事
如果两个表的 id 彼此相等,我尝试从一个表中获取数据。这是我使用的代码: SELECT id_to , email_to , name_to , status_to
我有一个 Excel 工作表。顶行对应于列名称,而连续的行每行代表一个条目。 如何将此 Excel 工作表转换为 SQL 表? 我使用的是 SQL Server 2005。 最佳答案 这取决于您使用哪
我想合并两个 Django 模型并创建一个模型。让我们假设我有第一个表表 A,其中包含一些列和数据。 Table A -------------- col1 col2 col3 col
我有两个表:table1,table2,如下所示 table1: id name 1 tamil 2 english 3 maths 4 science table2: p
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 1 年前。 Improve th
下面两个语句有什么区别? newTable = orginalTable 或 newTable.data(originalTable) 我怀疑 .data() 方法具有性能优势,因为它在标准 AX 中
我有一个表,我没有在其中显式定义主键,它并不是真正需要的功能......但是一位同事建议我添加一个列作为唯一主键以随着数据库的增长提高性能...... 谁能解释一下这是如何提高性能的? 没有使用索引(
如何将表“产品”中的产品记录与其不同表“图像”中的图像相关联? 我正在对产品 ID 使用自动增量。 我觉得不可能进行关联,因为产品 ID 是自动递增的,因此在插入期间不可用! 如何插入新产品,获取产品
我有一个 sql 表,其中包含关键字和出现次数,如下所示(尽管出现次数并不重要): ____________ dog | 3 | ____________ rat | 7 | ____
是否可以使用目标表中的LAST_INSERT_ID更新源表? INSERT INTO `target` SELECT `a`, `b` FROM `source` 目标表有一个自动增量键id,我想将其
我正在重建一个搜索查询,因为它在“我看到的”中变得多余,我想知道什么 (albums_artists, artists) ( ) does in join? is it for boosting pe
以下是我使用 mysqldump 备份数据库的开关: /usr/bin/mysqldump -u **** --password=**** --single-transaction --databas
我试图获取 MySQL 表中的所有行并将它们放入 HTML 表中: Exam ID Status Assigned Examiner
如何查询名为 photos 的表中的所有记录,并知道当前用户使用单个查询将哪些结果照片添加为书签? 这是我的表格: -- -- Table structure for table `photos` -
我的网站都在 InnoDB 表上运行,目前为止运行良好。现在我想知道在我的网站上实时发生了什么,所以我将每个页面浏览量(页面、引荐来源网址、IP、主机名等)存储在 InnoDB 表中。每秒大约有 10
我在想我会为 mysql 准备两个表。一个用于存储登录信息,另一个用于存储送货地址。这是传统方式还是所有内容都存储在一张表中? 对于两个表...有没有办法自动将表 A 的列复制到表 B,以便我可以引用
我不是程序员,我从这个表格中阅读了很多关于如何解决我的问题的内容,但我的搜索效果不好 我有两张 table 表 1:成员 id*| name | surname -------------------
我知道如何在 ASP.NET 中显示真实表,例如 public ActionResult Index() { var s = db.StaffInfoDBSet.ToList(); r
我正在尝试运行以下查询: "insert into visits set source = 'http://google.com' and country = 'en' and ref = '1234
我是一名优秀的程序员,十分优秀!