Reactjs 反应物料界面多次塌陷

Reactjs 反应物料界面多次塌陷,reactjs,typescript,material-ui,nested-lists,collapse,Reactjs,Typescript,Material Ui,Nested Lists,Collapse,目前,我的列表都已折叠,但它们链接到一个“打开”状态,因此如果我打开一个列表,所有其他列表都将打开。 什么是使折叠彼此分开的最好方法,而不必为每个列表设置很多状态 编辑:应用程序正在经历一个无限循环 App.tsx interface IState { error: any, intro: any, threads: any[], title: any, } export default class App extends React.Component<{}, IState> {

目前,我的列表都已折叠,但它们链接到一个“打开”状态,因此如果我打开一个列表,所有其他列表都将打开。 什么是使折叠彼此分开的最好方法,而不必为每个列表设置很多状态

编辑:应用程序正在经历一个无限循环

App.tsx

interface IState {
error: any,
intro: any,
threads: any[],
title: any,
}

export default class App extends React.Component<{}, IState> {
    constructor (props : any) {
        super (props);

        this.state = {
            error: "",
            intro: "Welcome to RedQuick",
            threads: [],
            title: ""
        };

        this.getRedditPost = this.getRedditPost.bind(this)
        this.handleClick = this.handleClick.bind(this)
    }

    public getRedditPost = async (e : any) => {
        e.preventDefault();

        const subreddit = e.target.elements.subreddit.value;
        const redditAPI = await fetch('https://www.reddit.com/r/'+ subreddit +'.json');
        const data = await redditAPI.json();

        console.log(data);

        if (data.kind) {
            this.setState({
                error: undefined,
                intro: undefined,
                threads: data.data.children,
                title: data.data.children[0].data.subreddit.toUpperCase()
            });
        } else {
            this.setState({
                error: "Please enter a valid subreddit name",
                intro: undefined,
                threads: [],
                title: undefined
            });
        }
    }

    public handleClick = (index : any)  => {
        this.setState({ [index]: true });
    }

    public render() {
        return (
            <div>
                <Header 
                    getRedditPost={this.getRedditPost}
                />
                <p className="app__intro">{this.state.intro}</p>
                {
                    this.state.error === "" && this.state.title.length > 0 ?
                    <LinearProgress />:
                    <ThreadList 
                        error={this.state.error}
                        handleClick={this.handleClick}
                        threads={this.state.threads}
                        title={this.state.title}
                    />
                }   
            </div>
        );
    }
}
<div className="threadlist__subreddit_threadlist">
    <List>
        { props.threads.map((thread : any, index : any) => 
            <div key={index} className="threadlist__subreddit_thread">
                <Divider />
                <ListItem button={true} onClick={props.handleClick(index)}/* component="a" href={thread.data.url}*/ >
                    <ListItemText primary={thread.data.title} secondary={<p><b>Author: </b>{thread.data.author}</p>} />
                    {props[index] ? <ExpandLess /> : <ExpandMore />}
                </ListItem>
                <Collapse in={props[index]} timeout="auto" unmountOnExit={true}>
                    <p>POOP</p>
                </Collapse>
                <Divider />
            </div>
        ) }
    </List> 
</div>
interface-IState{
错误:任何,
简介:任何,
线程:任意[],
标题:任何,
}
导出默认类App扩展React.Component{
构造器(道具:任何){
超级(道具);
此.state={
错误:“”,
简介:“欢迎来到RedQuick”,
线程:[],
标题:“
};
this.getRedditPost=this.getRedditPost.bind(this)
this.handleClick=this.handleClick.bind(this)
}
public getRedditPost=async(e:any)=>{
e、 预防默认值();
const subreddit=e.target.elements.subreddit.value;
const redditAPI=wait fetch('https://www.reddit.com/r/“+subreddit+”.json');
const data=wait redditAPI.json();
控制台日志(数据);
if(data.kind){
这是我的国家({
错误:未定义,
简介:未定义,
线程:data.data.children,
标题:data.data.children[0].data.subreddit.toUpperCase()
});
}否则{
这是我的国家({
错误:“请输入有效的子Reddit名称”,
简介:未定义,
线程:[],
标题:未定义
});
}
}
public handleClick=(索引:any)=>{
this.setState({[index]:true});
}
公共渲染(){
返回(

{this.state.intro}

{ this.state.error==“”&&this.state.title.length>0? : } ); } }
Threadlist.tsx

interface IState {
error: any,
intro: any,
threads: any[],
title: any,
}

export default class App extends React.Component<{}, IState> {
    constructor (props : any) {
        super (props);

        this.state = {
            error: "",
            intro: "Welcome to RedQuick",
            threads: [],
            title: ""
        };

        this.getRedditPost = this.getRedditPost.bind(this)
        this.handleClick = this.handleClick.bind(this)
    }

    public getRedditPost = async (e : any) => {
        e.preventDefault();

        const subreddit = e.target.elements.subreddit.value;
        const redditAPI = await fetch('https://www.reddit.com/r/'+ subreddit +'.json');
        const data = await redditAPI.json();

        console.log(data);

        if (data.kind) {
            this.setState({
                error: undefined,
                intro: undefined,
                threads: data.data.children,
                title: data.data.children[0].data.subreddit.toUpperCase()
            });
        } else {
            this.setState({
                error: "Please enter a valid subreddit name",
                intro: undefined,
                threads: [],
                title: undefined
            });
        }
    }

    public handleClick = (index : any)  => {
        this.setState({ [index]: true });
    }

    public render() {
        return (
            <div>
                <Header 
                    getRedditPost={this.getRedditPost}
                />
                <p className="app__intro">{this.state.intro}</p>
                {
                    this.state.error === "" && this.state.title.length > 0 ?
                    <LinearProgress />:
                    <ThreadList 
                        error={this.state.error}
                        handleClick={this.handleClick}
                        threads={this.state.threads}
                        title={this.state.title}
                    />
                }   
            </div>
        );
    }
}
<div className="threadlist__subreddit_threadlist">
    <List>
        { props.threads.map((thread : any, index : any) => 
            <div key={index} className="threadlist__subreddit_thread">
                <Divider />
                <ListItem button={true} onClick={props.handleClick(index)}/* component="a" href={thread.data.url}*/ >
                    <ListItemText primary={thread.data.title} secondary={<p><b>Author: </b>{thread.data.author}</p>} />
                    {props[index] ? <ExpandLess /> : <ExpandMore />}
                </ListItem>
                <Collapse in={props[index]} timeout="auto" unmountOnExit={true}>
                    <p>POOP</p>
                </Collapse>
                <Divider />
            </div>
        ) }
    </List> 
</div>

{props.threads.map((线程:any,索引:any)=>
{props[index]?:}
大便

) }
您必须为每次折叠创建不同的状态,我建议使用setState动态地使用从map函数获得的索引,您可能必须将index参数传递给handleClick函数,并基于此更改状态

<div className="threadlist__subreddit_threadlist">
    <List>
        { props.threads.map((thread : any, index : any) => 
            <div key={index} className="threadlist__subreddit_thread">
                <Divider />
                <ListItem button={true} onClick={props.handleClick(index)}/* component="a" href={thread.data.url}*/ >
                    <ListItemText primary={thread.data.title} secondary={<p><b>Author: </b>{thread.data.author}</p>} />
                    {props[index] ? <ExpandLess /> : <ExpandMore />}
                </ListItem>
                <Collapse in={props[index]} timeout="auto" unmountOnExit={true}>
                    <p>POOP</p>
                </Collapse>
                <Divider />
            </div>
        ) }
    </List> 
</div>

我是这样做的:

function DrawerMenuItems() {
  const [selectedIndex, setSelectedIndex] = React.useState("")

  const handleClick = index => {
    if (selectedIndex === index) {
      setSelectedIndex("")
    } else {
      setSelectedIndex(index)
    }
  }
  return (
    <List
      component="nav"
      aria-labelledby="nested-list-subheader"
      subheader={
        <ListSubheader component="div" id="nested-list-subheader">
          Nested List Items
        </ListSubheader>
      }
    >
      {drawerMenuItemData.map((item, index) => {
        return (
          <List>
            <ListItem
              key={index}
              button
              onClick={() => {
                handleClick(index)
              }}
            >
              <ListItemIcon>
                <item.icon />
              </ListItemIcon>
              <ListItemText primary={item.title} />
              {index === selectedIndex ? <ExpandLess /> : <ExpandMore />}
            </ListItem>
            <Collapse in={index === selectedIndex} timeout="auto" unmountOnExit>
              <List component="div" disablePadding>
                {item.submenu.map((sub, index) => {
                  return (
                    <ListItem button >
                      <ListItemText primary={sub.name} />
                    </ListItem>
                  )
                })}
              </List>
            </Collapse>
          </List>
        )
      })}
    </List>
  )
}
函数drawermenueItems(){
常量[selectedIndex,setSelectedIndex]=React.useState(“”)
const handleClick=索引=>{
if(selectedIndex==索引){
setSelectedIndex(“”)
}否则{
设置选定索引(索引)
}
}
返回(
{drawerMenuItemData.map((项,索引)=>{
返回(
{
handleClick(索引)
}}
>
{index==selectedIndex?:}
{item.submenu.map((子菜单,索引)=>{
返回(
)
})}
)
})}
)
}

这真的很模糊,但你可以软化列表并传递一个开放状态,其中一个是抱歉,我编辑了问题,因此更容易理解。我添加了一个答案和可能的解决方案。动态打开状态更改handleClick函数时,它在openArray[index]部分给出一个错误“error TS1005:”:“expected.”。另外,使用prevState允许折叠在打开后关闭不是最好的吗?但是我在使用prevState时也收到一个错误是的,你可以用prevState来做,我给了你一个小例子,不是完整的答案,我编辑了,但它应该可以正常工作。这会给你一个typescript错误,我帮不了你,muchI也不知道你是如何创建handleClick的,因为你没有共享它,这很难帮助你,因为你必须通过索引才能在组件中运行函数,比如:props.handleClick(index),你试过我的代码吗?我也这样解决了我的问题,但我目前有一个问题,当您单击嵌套项时,如何使其保持打开状态?在这种情况下,您可以在
useState
中使用数组而不是字符串。然后只需将项目键存储在其中,并在折叠时将其移除。