好的,我是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
行的查找。单击后,我为每一行都有一个“编辑”
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方式执行此操作…任何人都可以帮忙吗?
裁判是 不是 在这里使用合适的工具。
相反,您应该提升状态( 很多 )。
为此,我建议
<Header />
,<Row />
等),并在公共父级中将其拆分<App />
为单独的<EditDialog />
/ <DeleteDialog />
组件以编辑/删除行数据)-较小的组件更易于维护和解决id
的表)存储在parent(<Table />
)组件中,并将与表行相对应的数据条目作为参数传递给<Row />
组件onEdit()
和onDelete()
事件处理程序作为道具传递给<Row />
组件,并将其附加到/ 按钮的onClick()
处理程序Edit``Delete
onEdit()
,onDelete()
)绑定到父项中的回调,这将触发编辑/删除对话框<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(recordData),
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>
问题内容: 我对React和Redux非常陌生,我正在尝试将数据从一个组件传递到另一个组件。但它没有父子关系,并且彼此独立。谁能帮我做到这一点?下面是我的代码。 另一个文件是我想发送EmpNumber的位置, 问题答案: 好的,这是一个例子。我将假设您已经配置了所有Redux存储,即创建存储,rootReducer等…,因为这是一个单独的帖子。 因此,基本的想法是,当你想更新你的终极版商店状态你
问题内容: 我有一个调用会弹出一个的,以便用户可以选择目录。这些都是单独的类。从中传递值的正确方法是什么,以便我可以在中显示目录的路径? 编辑:更新了问题。 问题答案: 这是一个不完整的示例,但我想可以使您了解如何实现所需的目标。重要的一点是引用要在其中进行选择的属性,例如 参见下面如何将其放置在代码中: 希望对您有所帮助,对不起您没有提供完整的示例。 编辑 本质上,我们没有将任何参数传递给Abs
我的Navbar组件有2个子组件。每个组件都有自己的状态。在其组成部分内工作正常的国家。如何更新这两个状态从假到真的同时,当两个功能onclick将被执行? 主组件导航栏 列表菜单组件 汉堡包成分
本文向大家介绍vue.js组件之间传递数据的方法,包括了vue.js组件之间传递数据的方法的使用技巧和注意事项,需要的朋友参考一下 前言 组件是 vue.js 最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用。如何传递数据也成了组件的重要知识点之一。 组件 组件与组件之间,还存在着不同的关系。父子关系与兄弟关系(不是父子的都暂称为兄弟吧)。 父子组件 父子
本文向大家介绍react 父组件与子组件之间的值传递的方法,包括了react 父组件与子组件之间的值传递的方法的使用技巧和注意事项,需要的朋友参考一下 概念上,组件是封闭的环境。React中是单向数据流的设计,也就是是说只有父组件传递资料给子组件这回事。以正确的技术说明,拥有者组件可以设置被拥有者组件中的数据。 那么子组件要如何与父组件沟通这件事,简单的来说,是一种迂回的作法,在父组件中设置了一个
简而言之,我需要一个“购物车”一样的关系,从一个组件到网站的其余部分。我说“类似购物车”是因为它基本上是用户浏览时产生的需求列表。它不会有任何价格或税收逻辑,但每种类型的需求都有其“自己的< code >子参数,与我正在为其创建< code >接口的其他需求不同。我认为< code >需求组件将使用< code>any类型来接受输入的数据块。 截至目前,创建@Inputs和穿过整个树的大规模高速公