Reactjs 使用render from函数反应Typescript无限循环
我使用了一个动态状态来为每个ListItem提供一个单独的状态,以便折叠是否打开。但是,由于我必须向handleClick函数传递一个参数,因此我的渲染将经历一个无限循环 我得到的错误是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
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)=>()=>{…}
。
}
第一个选项将标记tslintjsx 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]}
??