React JS - Material UI ListItem (with Collapse API) onClick expands/collapse all sub list items instead of the selected one
React JS - Material UI ListItem (with Collapse API) onClick expands/collapse all sub list items instead of the selected one
我正在使用 React JS 实现 List 的 Expand/Collapse 功能 - Material UI ListItem(带折叠 API)
当我单击 ListItem 时,它 expands/collapse 所有子列表项而不是选定项。
这是示例代码。看起来我在其中一个元素中不正确地设置了键值,但无法弄清楚。有人能帮我吗?如果信息不足请告诉我
贾法尔
class CategoriesResults extends Component {
constructor(props) {
super(props);
this.state = {
open: false
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log("Handle Clicked....");
this.setState(prevState => ({
open: !prevState.open
}));
}
render() {
const docs = data.documents; //this coming from a json file, please see below for the sample json
return (
<div>
<List component='nav' aria-labelledby='nested-list-subheader'>
{docs.map(doc => {
return (
<div key={doc.Id}>
<ListItem button key={doc.Id} onClick={this.handleClick}>
<ListItemText primary={doc.Name} />
{this.state.open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse
key={doc.Sheets.Id}
in={this.state.open}
timeout='auto'
unmountOnExit
>
<List component='li' disablePadding key={doc.Id}>
{doc.Sheets.map(sheet => {
return (
<ListItem button key={sheet.Id}>
<ListItemIcon>
<InsertDriveFileTwoToneIcon />
</ListItemIcon>
<ListItemText key={sheet.Id} primary={sheet.Title} />
</ListItem>
);
})}
</List>
</Collapse>
<Divider />
</div>
);
})}
</List>
</div>
);
}
}
**Sample JSON**
{
"documents": [
{
"Id": 1,
"Name": "Category 1",
"Sheets": [
{
"Id": 1,
"Title": "Title1 "
},
{
"Id": 2,
"Title": "Title 2"
},
{
"Id": 3,
"Title": "Title 3"
}
]
}
}
您的所有 ListItem 都基于相同的状态展开。
如果 open 是 true
,它们的 Collapse
组件中都会得到 in=true
,所以它们都被展开了。
要解决这个问题,您应该将可扩展的 ListItem 提取到一个单独的组件中,该组件将管理它自己的状态:
class CustomizedListItem extends React.Component {
constructor(props) {
super(props);
this.state = {
open: false
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log("Handle Clicked....");
this.setState(prevState => ({
open: !prevState.open
}));
}
render(){
const { doc } = this.props;
return (
<div>
<ListItem button key={doc.Id} onClick={this.handleClick}>
<ListItemText primary={doc.Name} />
{this.state.open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse
key={doc.Sheets.Id}
in={this.state.open}
timeout='auto'
unmountOnExit
>
<List component='li' disablePadding key={doc.Id}>
{doc.Sheets.map(sheet => {
return (
<ListItem button key={sheet.Id}>
<ListItemIcon>
{/* <InsertDriveFileTwoToneIcon /> */}
</ListItemIcon>
<ListItemText key={sheet.Id} primary={sheet.Title} />
</ListItem>
);
})}
</List>
</Collapse>
<Divider />
</div>
)
}
}
export default class CategoriesResults extends React.Component {
render() {
const docs = data.documents; //this coming from a json file, please see below for the sample json
return (
<div>
<List component='nav' aria-labelledby='nested-list-subheader'>
{docs.map(doc => {
return (
<CustomizedListItem key={doc.id} doc={doc} />
);
})}
</List>
</div>
);
}
}
我使用了 class 组件,因为您在问题中使用了它。如果你想看到与 react-hooks 相同的解决方案,请告诉我:)
我已经把它转换成一个基于函数的组件,使用 hooks 这样未来的人可以很容易地理解它:
import React, { useState } from 'react'
const CustomizedListItem = ({ doc }) => {
const [ open, setOpen ] = useState(false)
const handleClick = () => {
setOpen(!open)
}
return (
<div>
<ListItem button key={doc.Id} onClick={handleClick}>
<ListItemText primary={doc.Name} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse
key={doc.Sheets.Id}
in={open}
timeout='auto'
unmountOnExit
>
<List component='li' disablePadding key={doc.Id}>
{doc.Sheets.map(sheet => {
return (
<ListItem button key={sheet.Id}>
<ListItemIcon>
{/* <InsertDriveFileTwoToneIcon /> */}
</ListItemIcon>
<ListItemText key={sheet.Id} primary={sheet.Title} />
</ListItem>
)
})}
</List>
</Collapse>
<Divider />
</div>
)
}
export default function CategoriesResults() {
const docs = data.documents //this coming from a json file
return (
<div>
<List component='nav' aria-labelledby='nested-list-subheader'>
{docs.map(doc => {
return (
<CustomizedListItem key={doc.id} doc={doc} />
)
})}
</List>
</div>
)
}
我正在使用 React JS 实现 List 的 Expand/Collapse 功能 - Material UI ListItem(带折叠 API)
当我单击 ListItem 时,它 expands/collapse 所有子列表项而不是选定项。
这是示例代码。看起来我在其中一个元素中不正确地设置了键值,但无法弄清楚。有人能帮我吗?如果信息不足请告诉我
贾法尔
class CategoriesResults extends Component {
constructor(props) {
super(props);
this.state = {
open: false
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log("Handle Clicked....");
this.setState(prevState => ({
open: !prevState.open
}));
}
render() {
const docs = data.documents; //this coming from a json file, please see below for the sample json
return (
<div>
<List component='nav' aria-labelledby='nested-list-subheader'>
{docs.map(doc => {
return (
<div key={doc.Id}>
<ListItem button key={doc.Id} onClick={this.handleClick}>
<ListItemText primary={doc.Name} />
{this.state.open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse
key={doc.Sheets.Id}
in={this.state.open}
timeout='auto'
unmountOnExit
>
<List component='li' disablePadding key={doc.Id}>
{doc.Sheets.map(sheet => {
return (
<ListItem button key={sheet.Id}>
<ListItemIcon>
<InsertDriveFileTwoToneIcon />
</ListItemIcon>
<ListItemText key={sheet.Id} primary={sheet.Title} />
</ListItem>
);
})}
</List>
</Collapse>
<Divider />
</div>
);
})}
</List>
</div>
);
}
}
**Sample JSON**
{
"documents": [
{
"Id": 1,
"Name": "Category 1",
"Sheets": [
{
"Id": 1,
"Title": "Title1 "
},
{
"Id": 2,
"Title": "Title 2"
},
{
"Id": 3,
"Title": "Title 3"
}
]
}
}
您的所有 ListItem 都基于相同的状态展开。
如果 open 是 true
,它们的 Collapse
组件中都会得到 in=true
,所以它们都被展开了。
要解决这个问题,您应该将可扩展的 ListItem 提取到一个单独的组件中,该组件将管理它自己的状态:
class CustomizedListItem extends React.Component {
constructor(props) {
super(props);
this.state = {
open: false
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log("Handle Clicked....");
this.setState(prevState => ({
open: !prevState.open
}));
}
render(){
const { doc } = this.props;
return (
<div>
<ListItem button key={doc.Id} onClick={this.handleClick}>
<ListItemText primary={doc.Name} />
{this.state.open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse
key={doc.Sheets.Id}
in={this.state.open}
timeout='auto'
unmountOnExit
>
<List component='li' disablePadding key={doc.Id}>
{doc.Sheets.map(sheet => {
return (
<ListItem button key={sheet.Id}>
<ListItemIcon>
{/* <InsertDriveFileTwoToneIcon /> */}
</ListItemIcon>
<ListItemText key={sheet.Id} primary={sheet.Title} />
</ListItem>
);
})}
</List>
</Collapse>
<Divider />
</div>
)
}
}
export default class CategoriesResults extends React.Component {
render() {
const docs = data.documents; //this coming from a json file, please see below for the sample json
return (
<div>
<List component='nav' aria-labelledby='nested-list-subheader'>
{docs.map(doc => {
return (
<CustomizedListItem key={doc.id} doc={doc} />
);
})}
</List>
</div>
);
}
}
我使用了 class 组件,因为您在问题中使用了它。如果你想看到与 react-hooks 相同的解决方案,请告诉我:)
我已经把它转换成一个基于函数的组件,使用 hooks 这样未来的人可以很容易地理解它:
import React, { useState } from 'react'
const CustomizedListItem = ({ doc }) => {
const [ open, setOpen ] = useState(false)
const handleClick = () => {
setOpen(!open)
}
return (
<div>
<ListItem button key={doc.Id} onClick={handleClick}>
<ListItemText primary={doc.Name} />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse
key={doc.Sheets.Id}
in={open}
timeout='auto'
unmountOnExit
>
<List component='li' disablePadding key={doc.Id}>
{doc.Sheets.map(sheet => {
return (
<ListItem button key={sheet.Id}>
<ListItemIcon>
{/* <InsertDriveFileTwoToneIcon /> */}
</ListItemIcon>
<ListItemText key={sheet.Id} primary={sheet.Title} />
</ListItem>
)
})}
</List>
</Collapse>
<Divider />
</div>
)
}
export default function CategoriesResults() {
const docs = data.documents //this coming from a json file
return (
<div>
<List component='nav' aria-labelledby='nested-list-subheader'>
{docs.map(doc => {
return (
<CustomizedListItem key={doc.id} doc={doc} />
)
})}
</List>
</div>
)
}