React - 超出最大调用堆栈大小

时间:2017-08-27 20:12:09

标签: javascript reactjs

我正在使用我的岳父让我建立的网站作为学习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;

2 个答案:

答案 0 :(得分:3)

如果你写

onClick={ this.changeCurrentBook(publication) } 

该函数将立即执行,计算出的值将传递给onClick。 你需要的是运行一个代码,它立即返回一个将在点击时调用的函数。为此,请从onClick组件中更改Publication调用

onClick={ this.changeCurrentBook(publication) } 

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

作为进一步的改进,还值得注意的是,在渲染内部编写箭头函数会产生一些性能影响。实际上,每次渲染Publication组件时,它都会生成一个新的相同onClick函数,这反过来会强制组件重新渲染。

为了避免额外无用的渲染,让我们更改处理程序以返回一个将在点击时调用的函数:

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

这样我们在渲染方法中不需要任何箭头功能,我们也不会有任何额外的渲染:

 onClick={ this.changeCurrentBook(publication) }

有关详细说明,请参阅here

答案 1 :(得分: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);
}
相关问题