Reactjs 使用render from函数反应Typescript无限循环

Reactjs 使用render from函数反应Typescript无限循环,reactjs,typescript,render,Reactjs,Typescript,Render,我使用了一个动态状态来为每个ListItem提供一个单独的状态,以便折叠是否打开。但是,由于我必须向handleClick函数传递一个参数,因此我的渲染将经历一个无限循环 我得到的错误是 Lambdas are forbidden in JSX attributes due to their rendering performance impact 它不允许我使用Lambdas,所以我不能这样做 <ListItem button={true} onClick={() => prop

我使用了一个动态状态来为每个ListItem提供一个单独的状态,以便折叠是否打开。但是,由于我必须向handleClick函数传递一个参数,因此我的渲染将经历一个无限循环

我得到的错误是

Lambdas are forbidden in JSX attributes due to their rendering performance impact
它不允许我使用Lambdas,所以我不能这样做

<ListItem button={true} onClick={() => props.handleClick(index)}>
props.handleClick(索引)}>
我想知道是否有办法解决这个问题,这样我就可以对每个列表项使用handleClick和它们的索引值,而不必经过无限循环

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]?:}
大便

) }
错误:

超过最大更新深度。当一个组件 在componentWillUpdate或 组件更新。React将嵌套更新的数量限制为 防止无限循环


在这里使用咖喱概念,如下所示:

public handleClick = (index : any) = () => {
    this.setState({ [index]: true });
}
并以相同的方式使用handleClick:
onClick={props.handleClick(index)}


查看此答案以了解更多详细信息:

此问题是
onClick
需要一个函数,该函数可以处理
MouseEvent | undefined
的参数。但是,调用
onClick={handleClick(index)}
解析为意味着
handleClick(index)
在渲染时解析,并渲染为
onClick={undefined}

您需要将onClick处理程序更改为
onClick={()=>handleClick(index))
或将handleClick更改为
handleClick=(index)=>()=>{…}
。 }

第一个选项将标记tslint
jsx no lambda
规则,在这种情况下,您需要使用第二个选项

可能值得考虑禁用
jsx no lamda
,不过,该规则背后的目的是因为在每次渲染时都会创建一个新函数,这可能会对性能产生影响(在中讨论)。然而,这会使代码更难推理。通常,以牺牲可读性为代价过早地优化代码是不好的


如果您后来发现昂贵的渲染会从这种优化中受益,那么最好使用可读的解决方案,例如使用库(如

将其存储起来),问题如下:
onClick={props.handleClick(index)
,指定function not值,如下所示:
onClick={()=>props.handleClick(index)}
或使用currying概念:
public-handleClick=(index:any)=()=>{this.setState({[index]:true});}
检查此答案以了解更多详细信息。检查问题和讨论。如果我尝试分配函数,它会告诉我一个错误,即“lambda在JSX属性中是禁止的,因为它们会影响渲染性能”你的意思是public handleClick=(index:any)=>()=>{…}?不,谢谢,它修复了错误,但现在还有另一个问题。分享这个问题,我们也会找到解决方案:)所以一切都很好,但崩溃不适用于单击,我有控制台.log(props[index])在ThreadList.tsx内部,但首先它是未定义的,可能这就是问题所在?因为您没有在props中以索引形式从父级传递任何内容,所以您在此处指定的(预期)值是什么:
in={props[index]}
??