- 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/
或者存在像 这样的指针和引用C ? 我正在尝试开始使用 vala,但很高兴知道 vala 是“按引用传递”还是“按值传递” 最佳答案 首先你应该明白默认的vala编译器valac编译为 C(作为一种中
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我确实对 crypt() PHP 函数感到困惑。 当第二个 crypt 显然使用不同的第二个参数时,以下两个 crypt 函数如何给出相同的输出?差异盐意味着差异哈希对吗? echo crypt("p
我正在尝试在方案中模拟堆栈。我正在使用 DrScheme 并选择语言 R5RS。我需要创建 pop、push 和 peek 的函数。但我无法弄清楚如何通过引用传递。我已经阅读了一些关于盒子的信息,但是
我已经查过维基百科并用 google 搜索过,但我仍然无法理解 ALGOL 60 中的按名称传递的工作原理。 最佳答案 我在 Pass-By-Name Parameter Passing 找到了很好的
问题:我想知道在 Excel 2003 VBA 中处理数组的最佳解决方案是什么 背景:我在 Excel 2003 中有一个超过 5000 行的宏。我在过去 2 年中构建了它,将新功能添加为新过程,这有
我正在尝试反转位图数组,而不修改源数组。但问题是源数组也被颠倒了。我做错了什么还是我应该以其他方式做?感谢您的帮助。 private GalleryAdapter galleryAdapter; pr
因此,关于按引用传递/按值传递,方法如何处理参数传递已有详细记录,但是变量赋值又如何呢? 例如,我刚刚编写了一些如下所示的代码: TreeNode parent = null; TreeNode cu
我正在编写一个脚本,它将从我们的星号系统中回填调用详细记录到我们的 MySQL 日志数据库中。在下面的代码中,我试图忽略重复键并继续到下一行,但是当这段代码执行时,我所看到的只是第一行欺骗警告,然后脚
我从一个 Action (executeProcess)重定向到另一个(executeIndex)。我希望能够不使用GET传递参数/变量(例如$this->redirect('index', arra
我经常看到方法接口(interface)的两种相互冲突的策略,大致概括如下: // Form 1: Pass in an object. double calculateTaxesOwed(TaxFo
目前正在学习回调在 JavaScript 中的含义,我正在努力理解回调是如何工作的,以及术语“passing this”或“passing that”的来源以及它如何与回调一起工作?我想展示一些示例代
我通过 URL 传递参数并且页面被正确重定向。如何访问下一个(重定向的)页面上(从上一页)传递并在 URL 中可用的参数?谁能告诉我该怎么做? 或者有没有其他的方式在页面之间传递参数? 是否有类似 A
我通过 URL 传递参数并且页面被正确重定向。如何访问下一个(重定向的)页面上(从上一页)传递并在 URL 中可用的参数?谁能告诉我该怎么做? 或者有没有其他的方式在页面之间传递参数? 是否有类似 A
按引用传递和按名称传递的参数传递模式有什么区别这里是 Python 中的一个示例,但假设我们不使用任何 Python 规则: def P(x,y) global i y=1 prin
我正在编写自己的 LLVM pass,它修改了 LLVM 位码。在生成位码时,我想禁用函数内联,但是当我完成对位码的修改后,我想调用执行函数内联的传递。这个可以吗。如果是,如何? 为了更好地理解我在说
我有一个模板函数,负责将模板值写入流。它看起来像这样: template void Write( T value, std::ostream& stream, endianness_t endian
我一直在使用两个程序 llvm 的 opt 和 clifford wolf 的 yosys两者都有类似的通行证接口(interface)。(他们使用共享库作为优化 passes ) 我想根据我的 ll
在我们使用引用传递的 C++ 中,我们引用了我们从参数传递给函数参数的地址,它本质上是一个指针,对吗?因此,虽然它们本质上是相同的东西,别名和所有,但指针不也需要内存空间吗?因此,无论我们在参数函数中
这是一个关于 64 位整数的效率问题。假设我不需要修改“int”参数的值,我应该通过值还是引用传递它。 假设是 32 位机: 1) 32 位 int:我猜答案是“按值传递”,因为“按引用传递”会产生额
我是一名优秀的程序员,十分优秀!