2017-08-27 68 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); 
} 
相關問題