首页 > 解决方案 > 每次在 React JS 中调整浏览器大小时都会调用 ComponentDidMount

问题描述

我正在使用 React JS 开发一个 Web 应用程序。我是 React JS 的新手。我现在正在做的是从发出 api 请求的远程服务器获取数据并将它们显示在页面上。

但问题是,每当我调整浏览器大小时,总是会调用 React 组件的组件确实挂载事件。我在 componentDidMount 事件中进行 API 调用。因此,每当我调整浏览器的大小时,它都会对服务器进行额外的调用并刷新数据。那不应该发生。因此,为了确保 API 调用只进行一次,我在 componentDidMount 事件中检查使用状态,如下所示。

componentDidMount()
{
    if(!this.state.initialized)
    {
        //Api call
        this.fetchEvents(); 
    }
    this.setState({
        initialized: true
    })
}

上面的代码仍在向服务器发出 api 请求并刷新浏览器调整大小的数据。为什么会这样?如何预防?我喜欢了解它的内部运作,而不是立即解决它。

如果人们想查看代码,这是我的整个 EventListComponent

class EventListComponent extends Component {
    constructor(props) {
        super(props);   
        this.redirectToCreatePage = this.redirectToCreatePage.bind(this);
        this.redirectToEditPage = this.redirectToEditPage.bind(this);
        this.showDeleteEventConfirmation = this.showDeleteEventConfirmation.bind(this);
        this.closeDeleteConfirmation = this.closeDeleteConfirmation.bind(this);
        this.deleteEvent = this.deleteEvent.bind(this);
        this.state = {
            initialized :false
        }
    }

    componentDidMount()
    {
        if(!this.state.initialized)
        {
            this.fetchEvents(); 
        }
        this.setState({
            initialized: true
        })
    }

    fetchEvents()
    {
        this.props.startFetchingEvents();
        getHttpClient().get('event/list', { })
        .then((response) => {
            this.props.completeFetchingEvent(response.data);
        })
        .catch((error) => {
            this.props.errorFetchingEvents();
        });
    }

    redirectToEditPage(event)
    {
        // return alert(event.id)
        this.props.setEditingEvent(event);
        this.props.history.push({ 
           pathname : '/event/'+ event.id +'/edit'
        });
    }

    redirectToAlbum(event)
    {
        this.props.history.push("/event/" + event.code + "/album");
    }

    redirectToCreatePage()
    {
        this.props.history.push('event/create');
    }

    redirectToUploadPage(event)
    {
        this.props.history.push('event/' + event.id + '/file/upload')
    }

    redirectToMatchPhotosPage(event)
    {
        this.props.history.push('/event/' + event.id + '/match/photos');
    }

    showDeleteEventConfirmation(event)
    {
        this.props.promptDeleteConfirmation(event);
    }

    closeDeleteConfirmation()
    {
        this.props.closeDeleteConfirmation();
    }

    deleteEvent()
    {
        this.props.startDeletingEvent(this.props.eventToBeDeleted);
        let body = { id : this.props.eventToBeDeleted.id }
        let path = "event/delete";
        getHttpClient()
        .post(path, body)
        .then((response) => {
            this.props.completeDeletingEvent();
            window.location.reload()
        })
        .catch((error) => {
            this.props.errorDeletingEvent();
        });
    }

    render() {
        let eventWidgets = this.props.events.map((item, index)=> {
            return <Grid key={index} item sm={4} xs={4}>
            <EventWidget 
            showDeleteEventConfirmation={this.showDeleteEventConfirmation.bind(this)}
            redirectToUploadPage={this.redirectToUploadPage.bind(this)}
            redirectToAlbum={this.redirectToAlbum.bind(this)}
            redirectToEditPage={this.redirectToEditPage.bind(this)} 
            redirectToMatchPhotosPage={this.redirectToMatchPhotosPage.bind(this)}
            {...item} />
            </Grid>
        })

        return (
        <div className={scss['page-container']}>
        <Button onClick={this.redirectToCreatePage} color="secondary" type="button" variant="raised">Post new event</Button>



        <BlockUi tag="div" blocking={this.props.requestingEvents}>
        <Grid
        style={{ marginTop: "10px", minHeight: "100px" }}
        spacing={16}
        container
        justify="flex-start"
        >

            {eventWidgets}

        </Grid>
        </BlockUi>


        <Dialog
          open={this.props.showDeleteConfirmationDialog}
          onClose={this.closeDeleteConfirmation}
          aria-labelledby="alert-dialog-title"
          aria-describedby="alert-dialog-description"
        >
        <BlockUi tag="div" blocking={this.props.deletingEvent}>
          <DialogTitle id="alert-dialog-title">{"Confirmation"}</DialogTitle>
          <DialogContent>
            <DialogContentText id="alert-dialog-description">
              Are you sure to delete the event? You cannot undo the action.
            </DialogContentText>
          </DialogContent>
          <DialogActions>
            <Button onClick={this.closeDeleteConfirmation} color="primary">
              No
            </Button>
            <Button onClick={this.deleteEvent} color="primary" autoFocus>
              Yes
            </Button>
          </DialogActions>
        </BlockUi>
        </Dialog>

        </div>
        );
    }
}



function mapStateToProps(state)
{
    return {
        events: state.eventList.events,
        requestingEvents : state.eventList.requestingList,
        showDeleteConfirmationDialog : state.eventList.showDeleteConfirmationDialog,
        deletingEvent : state.eventList.deletingEvent,
        eventToBeDeleted : state.eventList.eventToBeDeleted
    };
}

function matchDispatchToProps(dispatch)
{
    return bindActionCreators({
        startFetchingEvents: EventListActions.startFetchingEvents,
        completeFetchingEvent: EventListActions.completeFetchingEvents,
        errorFetchingEvents : EventListActions.errorFetchingEvents,
        setEditingEvent: EditEventActions.setEditingEvent,
        promptDeleteConfirmation : EventListActions.promptDeleteConfirmation ,
        closeDeleteConfirmation : EventListActions.closeDeleteConfirmation,
        startDeletingEvent : EventListActions.startDeletingEvent,
        completeDeletingEvent : EventListActions.completeDeletingEvent,
        errorDeletingEvent : EventListActions.errorDeletingEvent
    }, dispatch);
}

EventListComponent.propTypes = {
  classes: PropTypes.shape({
    headerTheme: PropTypes.string
  }).isRequired
};

const enhance = compose(withWidth(), withStyles(themeStyles, { withTheme: true }), connect(mapStateToProps, matchDispatchToProps))

export default enhance(EventListComponent);

标签: reactjsreact-component

解决方案


推荐阅读