2017-08-27 103 views
0

我正在使用一个网站,我的岳父让我建立作为学习React的借口。我不是一个自然的JavaScript开发人员(在后端更快乐),并且知道我可能在我的代码中有一些递归元素,但我无法看到它。谁能告诉我我做错了什么?反应 - 超过最大调用堆栈大小

import React, { Component } from 'react'; 
import { Container, Segment, Grid, Image, Card, Divider, Header } from 'semantic-ui-react'; 
import publicationData from '../data/publicationData'; 

const Publication = (props) => (
    <Card> 
     <Image src={props.img_url} style={{ height: "350px", width: "auto", margin: "15px auto"}}/> 
     <Card.Content style={{textAlign: "center"}}> 
     <Card.Header >{props.title}</Card.Header> 
     </Card.Content> 
    </Card> 
); 



class Publications extends Component { 
    constructor(props) { 
     super(props); 

     this.state = { books: publicationData, currentBook: publicationData[0] }; 
     this.changeCurrentBook.bind(this); 

    } 
    changeCurrentBook(e) { 
     this.setState({ currentBook: e }); 
    } 
    render() { 
    return(
      <Segment basic> 
       <Container> 
        <Grid stackable> 
         <Grid.Row divided> 
          <Grid.Column width={8}> 
           <Image src={ this.state.currentBook.img_url } centered/> 
          </Grid.Column> 
          <Grid.Column width={8} verticalAlign="middle"> 
           <Header content={ this.state.currentBook.title} /> 
           <p>{ this.state.currentBook.blurb }</p> 
          </Grid.Column> 
         </Grid.Row> 
        </Grid> 
        <Grid.Row> 
        <Divider /> 
        <Grid.Column> 
         <Card.Group itemsPerRow={4} doubling stackable> 
          { this.state.books.map((publication) => { 
            return (
            <Publication 
             title={publication.title} 
             blurb={publication.blurb} 
             img_url={publication.img_url} 
             key={publication.title} 
             onClick={ this.changeCurrentBook(publication) } 
            /> 
           ) 
           }) 
          } 
         </Card.Group> 
        </Grid.Column> 
        </Grid.Row> 
       </Container> 
      </Segment> 
     ); 
    } 
} 

export default Publications; 
+0

你可以请加功能'changeCurrentBook'里面记录的语句,检查是否即使它正在执行或不在onclick事件中。 – RaghavGarg

+0

@RaghavGarg好的电话,它甚至没有开火。 –

+0

所以,在'Publication'组件中添加'onClick'时,你只是传递另一个道具;你必须在你的'Publication'组件中使用(绑定)它到一些'element'来实际激发它。 – RaghavGarg

回答

2

如果你写

onClick={ this.changeCurrentBook(publication) } 

的功能将被立即执行,并计算出的值将被传递给onClick。 你需要的是运行一个代码,它立即返回一个将在点击时调用的函数。要做到这一点,从

onClick={ this.changeCurrentBook(publication) } 

Publication组件内改变onClick调用到

onClick = {() => this.changeCurrentBook(publication)} 

作为进一步的改进,这也是值得注意的是,写里面的渲染箭头功能有一定的性能影响。实际上,每次渲染组件Publication时,它都会生成一个新的相同的onClick函数,这又会强制组件重新渲染。

为了避免多余无用的效果图,让我们改变处理程序返回,这将在点击调用的函数:

changeCurrentBook(e) { 
    return function() { 
    this.setState({ currentBook: e }); 
    } 
} 

这样,我们不需要任何箭头函数内部渲染方法,我们也不会有任何额外的渲染:

onClick={ this.changeCurrentBook(publication) } 

作进一步的解释见here

+0

谢谢,它阻止了超出最大调用堆栈大小。不幸的是,代码似乎没有做我想做的事 - 虽然onClick没有更新页面。你有什么机会可以看到那里有什么问题吗?一旦时间限制进展,你会接受你的答案。 –

+0

一个小的解释可以很好地补充,这样OP就会明白他在哪里犯了一个错误。 – RaghavGarg

1

撰写您Publication组件的onClick这样

<Publication 
    title={publication.title} 
    blurb={publication.blurb} 
    img_url={publication.img_url} 
    key={publication.title} 
    onClick={() => this.changeCurrentBook(publication) } 
/> 

还需要绑定你的方法是这样

constructor(props) { 
    super(props); 
    this.state = { books: publicationData, currentBook: publicationData[0] }; 
    this.changeCurrentBook = this.changeCurrentBook.bind(this); 
} 
相关问题