如何在 <List> 中将元素数组呈现为 <Dialog>
How to render array of elements as <Dialog> in a <List>
我正在构建一个组件,<ElementList>
,它接收 props 中的元素数组,并且 builds 一个 <List>
,其中每个 <ListItem>
是数组的一个元素。
我正在向 <ListItem>
传递一个名为 <ElementShow>
的单独组件,它包装了一个 material-ui <Dialog>
组件。
单击 <ListItem>
时,它应该打开特定 <ElementShow>
组件的 <Dialog>
。
目前,当我单击任何 <ListItem>
时,它会打开数组最后一个元素的 <Dialog>
,无论我单击哪个 <ListItem>
。
参考代码如下:
ElementList.js
import React from 'react'
import {List, ListItem} from 'material-ui/List'
import Subheader from 'material-ui/Subheader'
import ElementShow from './ElementShow'
class ElementList extends React.Component {
constructor() {
super()
this.state = {
dialogOpen: false
}
}
handleOpen = () => {
this.setState({dialogOpen: true})
}
handleClose = () => {
this.setState({dialogOpen: false})
}
renderElements () {
const {elements} = this.props
if (elements.length < 1) {
return (
<ListItem
key='empty_element'
primaryText='No Elements Yet'
/>
)
} else {
return elements.map(element => {
return (
<ListItem
key={element._id}
primaryText={element.name}
onClick={this.handleOpen}
>
<ElementShow
dialogOpen={this.state.dialogOpen}
handleClose={this.handleClose} element={element} />
</ListItem>
)
})
}
}
render () {
return (
<List className='box'>
<Subheader>Elements</Subheader>
{this.renderElements()}
</List>
)
}
}
export default ElementList
ElementShow.js
import React from 'react'
import Dialog from 'material-ui/Dialog'
class ElementShow extends React.Component {
constructor (props) {
super(props)
this.state = {
open: props.dialogOpen
}
}
render () {
const { element, handleClose } = this.props
return (
<Dialog
title={element.name}
modal={false}
open={this.props.dialogOpen}
onRequestClose={handleClose}>
{element}
</Dialog>
)
}
}
export default ElementShow
我想我需要 link 将对话状态设置为特定角色,但我还没有找到可行的方法。
任何 help/tips 不胜感激!
好吧,你遇到的一个问题是 this.state
是父组件的状态,并不特定于每个子组件 - 所以当你写
elements.map((element) => {
...
<ElementShow dialoagOpen={ this.state.dialogOpen } />
})
它会影响所有元素。
我会做的是
class ElementList {
onClickElement = (element) => {
this.setState({
dialogOpen: true,
selectedElement: element
});
}
render() {
const mElements = elements.map((element) => {
/* I would suggest using a partial here, as opposed to what I've written */
return <ListItem onClick={ () => { this.onClickElement(element) } } />
});
const { selectedElement } = this.state;
return (
<div>
<List className='box'>
<Subheader>Elements</Subheader>
{ mElements }
</List>
{ selectedElement && (
<Dialog
title={ selectedElement.name }
modal={ false}
open={ this.state.dialogOpen }
element={ selectedElement }
onRequestClose={ this.handleClose }
>
{ selectedElement }
</Dialog>
) }
</div>
)
}
}
我认为这将实现您想要的。当您想隐藏对话框时,将 this.state.dialogOpen
设置为 false
并清除 this.state.selectedElement
。
您需要为呈现的每个对话框设置单独的状态(true 或 false)。
将每个元素的索引传递给您的 handleOpen
和 handleClose
函数,并使用它来切换正确的状态。
return elements.map((element, index) => {
return (
<ListItem
key={element._id}
primaryText={element.name}
onClick={() => this.handleOpen(index)}
>
<ElementShow
dialogOpen={this.state.dialogOpen[index]}
handleClose={this.handleClose(index)} element={element} />
</ListItem>
)
})
接下来,将您的状态设置为与元素数量相等的数组,并将第一个对话框初始化为打开状态。在您的 open/close 函数中包含索引以访问部分数组。
constructor(props) {
super(props)
this.state = {
dialogOpen: props.element.map((element, index) => {
return index === 0 ? true : false;
}
}
}
handleOpen = (index) => {
this.setState({ dialogOpen[index]: true })
}
handleClose = (index) => {
this.setState({ dialogOpen[index]: false })
}
对于任何使用钩子的人,这里是我的解决方案:
const [openDialog, setDialogOpen] = React.useState(false);
const [selectedElement, setSelectedElement] = React.useState();
const handleDialogOpen = (element) => {
setDialogOpen(true);
setSelectedElement(element);
};
return (
{elements.map((e) => (
...
<CardActionArea onClick={() => handleDialogOpen(e)}>
...
{selectedElement && (
<EditDialog
selectedElement={selectedElement}
openDialog={openDialog}
setOpenDialog={setDialogOpen}
/>
)}
))}
)
我正在构建一个组件,<ElementList>
,它接收 props 中的元素数组,并且 builds 一个 <List>
,其中每个 <ListItem>
是数组的一个元素。
我正在向 <ListItem>
传递一个名为 <ElementShow>
的单独组件,它包装了一个 material-ui <Dialog>
组件。
单击 <ListItem>
时,它应该打开特定 <ElementShow>
组件的 <Dialog>
。
目前,当我单击任何 <ListItem>
时,它会打开数组最后一个元素的 <Dialog>
,无论我单击哪个 <ListItem>
。
参考代码如下:
ElementList.js
import React from 'react'
import {List, ListItem} from 'material-ui/List'
import Subheader from 'material-ui/Subheader'
import ElementShow from './ElementShow'
class ElementList extends React.Component {
constructor() {
super()
this.state = {
dialogOpen: false
}
}
handleOpen = () => {
this.setState({dialogOpen: true})
}
handleClose = () => {
this.setState({dialogOpen: false})
}
renderElements () {
const {elements} = this.props
if (elements.length < 1) {
return (
<ListItem
key='empty_element'
primaryText='No Elements Yet'
/>
)
} else {
return elements.map(element => {
return (
<ListItem
key={element._id}
primaryText={element.name}
onClick={this.handleOpen}
>
<ElementShow
dialogOpen={this.state.dialogOpen}
handleClose={this.handleClose} element={element} />
</ListItem>
)
})
}
}
render () {
return (
<List className='box'>
<Subheader>Elements</Subheader>
{this.renderElements()}
</List>
)
}
}
export default ElementList
ElementShow.js
import React from 'react'
import Dialog from 'material-ui/Dialog'
class ElementShow extends React.Component {
constructor (props) {
super(props)
this.state = {
open: props.dialogOpen
}
}
render () {
const { element, handleClose } = this.props
return (
<Dialog
title={element.name}
modal={false}
open={this.props.dialogOpen}
onRequestClose={handleClose}>
{element}
</Dialog>
)
}
}
export default ElementShow
我想我需要 link 将对话状态设置为特定角色,但我还没有找到可行的方法。
任何 help/tips 不胜感激!
好吧,你遇到的一个问题是 this.state
是父组件的状态,并不特定于每个子组件 - 所以当你写
elements.map((element) => {
...
<ElementShow dialoagOpen={ this.state.dialogOpen } />
})
它会影响所有元素。
我会做的是
class ElementList {
onClickElement = (element) => {
this.setState({
dialogOpen: true,
selectedElement: element
});
}
render() {
const mElements = elements.map((element) => {
/* I would suggest using a partial here, as opposed to what I've written */
return <ListItem onClick={ () => { this.onClickElement(element) } } />
});
const { selectedElement } = this.state;
return (
<div>
<List className='box'>
<Subheader>Elements</Subheader>
{ mElements }
</List>
{ selectedElement && (
<Dialog
title={ selectedElement.name }
modal={ false}
open={ this.state.dialogOpen }
element={ selectedElement }
onRequestClose={ this.handleClose }
>
{ selectedElement }
</Dialog>
) }
</div>
)
}
}
我认为这将实现您想要的。当您想隐藏对话框时,将 this.state.dialogOpen
设置为 false
并清除 this.state.selectedElement
。
您需要为呈现的每个对话框设置单独的状态(true 或 false)。
将每个元素的索引传递给您的 handleOpen
和 handleClose
函数,并使用它来切换正确的状态。
return elements.map((element, index) => {
return (
<ListItem
key={element._id}
primaryText={element.name}
onClick={() => this.handleOpen(index)}
>
<ElementShow
dialogOpen={this.state.dialogOpen[index]}
handleClose={this.handleClose(index)} element={element} />
</ListItem>
)
})
接下来,将您的状态设置为与元素数量相等的数组,并将第一个对话框初始化为打开状态。在您的 open/close 函数中包含索引以访问部分数组。
constructor(props) {
super(props)
this.state = {
dialogOpen: props.element.map((element, index) => {
return index === 0 ? true : false;
}
}
}
handleOpen = (index) => {
this.setState({ dialogOpen[index]: true })
}
handleClose = (index) => {
this.setState({ dialogOpen[index]: false })
}
对于任何使用钩子的人,这里是我的解决方案:
const [openDialog, setDialogOpen] = React.useState(false);
const [selectedElement, setSelectedElement] = React.useState();
const handleDialogOpen = (element) => {
setDialogOpen(true);
setSelectedElement(element);
};
return (
{elements.map((e) => (
...
<CardActionArea onClick={() => handleDialogOpen(e)}>
...
{selectedElement && (
<EditDialog
selectedElement={selectedElement}
openDialog={openDialog}
setOpenDialog={setDialogOpen}
/>
)}
))}
)