1

我正在开发一个使用 ReactJS 作为前端的网络应用程序。我意识到当我在组件中的选项卡之间切换时,它非常慢并且往往会滞后(动画不流畅)。我想不出为什么会这样,因为我的组件似乎没有不必要地重新渲染。下面是我的代码片段。

class SalesProjectDetail extends Component {

    state = {
    }


    componentDidMount() {
        this.props.initial()
    };

    requirement = (project) => {
        console.log('hi')
        let component = (
            <React.Fragment>
                <RequirementCreateDrawer id={this.props.match.params.id} />
                <RequirementDeleted requirements={project.requirements.filter(requirement => requirement.status === 'inactive')} />
                <RequirementTimeline requirements={project.requirements.filter(requirement => requirement.status === 'active')} />
            </React.Fragment>
        )
        if (this.props.loadingComponent === 'requirement') {
            return (
                <Spin size='large'>
                    {component}
                </Spin>
            )
        }
        return component
    }

    quotation = (project, type) => {
        let component = (type == 'PQ') ?
            (<React.Fragment>
                <QuotationCreateDrawer type="PQ" id={this.props.match.params.id} />
                <QuotationDeleted quotations={project.quotations.filter(quotation => quotation.direction == 'pq').filter(quotation => quotation.status == 'inactive')} type='pq' />
                <QuotationTable quotations={project.quotations.filter(quotation => quotation.direction == 'pq').filter(quotation => quotation.status == 'active')} type='pq' />
            </React.Fragment>)
            :
            (<React.Fragment>
                <QuotationCreateDrawer type="SQ" id={this.props.match.params.id} />
                <QuotationDeleted quotations={project.quotations.filter(quotation => quotation.direction == 'sq').filter(quotation => quotation.status == 'inactive')} type='sq' />
                <QuotationTable quotations={project.quotations.filter(quotation => quotation.direction == 'sq').filter(quotation => quotation.status == 'active')} type='sq' />
            </React.Fragment>)

        if (this.props.loadingComponent === 'quotation') {
            return (
                <Spin size='large'>
                    {component}
                </Spin>
            )
        }
        return component
    }

    notation = (project) => {
        let component = (
            <React.Fragment>
                <NotationList notations={project.notations.filter(notation => notation.status == 'active')} id={project.sales_project_id} />
                <NotationDeleted notations={project.notations.filter(notation => notation.status == 'inactive')} />
            </React.Fragment>
        )
        if (this.props.loadingComponent === 'notation') {
            return (
                <Spin size='large'>
                    {component}
                </Spin>
            )
        }
        return component
    }

    render() {
        console.log('bad')
        const project = this.props.project
        return (
            this.props.loading['salesproject'] === false ?
                <React.Fragment>
                    <Card style={{ height: 'auto', padding: 0, margin: 0 }}>
                        <Row>
                            <Col span={4}>
                                {this.props.loadingComponent === 'project' ?
                                    <Spin size='large'>
                                        <ProjectCard project={project} />
                                    </Spin>
                                    : <ProjectCard project={project} />}
                            </Col>
                            <Col span={20} style={{ backgroundColor: '#fff', padding: '1% 2%' }} >

                                <Tabs defaultActiveKey="0">
                                    <TabPane tab={<span><GithubOutlined />Activities</span>} key="0">
                                        <ActivitiesTimeline project={project} />
                                    </TabPane>
                                    <TabPane
                                        tab={<span><AppleOutlined />Requirements</span>}
                                        key="1"
                                    >
                                        {this.requirement(project)}
                                    </TabPane>


                                    <TabPane
                                        tab={<span><AndroidOutlined />Quotations</span>}
                                        key="2"
                                    >
                                        <Tabs defaultActiveKey="0" tabPosition="left">

                                            <TabPane tab={<span><ClockCircleOutlined /></span>} key="0" >
                                                <QuotationTimeline quotations={project.quotations} />
                                            </TabPane>

                                            <TabPane tab="PQ" key="1">
                                                {this.quotation(project, 'PQ')}
                                            </TabPane>

                                            <TabPane tab="SQ" key="2">
                                                {this.quotation(project, 'SQ')}
                                            </TabPane>
                                        </Tabs>
                                    </TabPane>


                                    <TabPane
                                        tab={<span><WindowsOutlined />Notations</span>}
                                        key="3"
                                    >
                                        {this.notation(project)}
                                    </TabPane>
                                </Tabs>
                            </Col>
                        </Row >
                    </Card>
                    <WorkflowObjectComponent
                        workflow_class={project.workflow_id}
                        {...this.props}
                    />
                </React.Fragment>

                :

                <div style={{ textAlign: 'center' }}><Spin size='large' /></div>
        )
    }

}

const mapStateToProps = state => ({
    loading: state.api.loading,
    project: state.api.project,
    loadingComponent: state.api.loadingComponent
})

const mapDispatchToProps = (dispatch, ownProps) => {
    return {
        initial: () => dispatch({ type: 'SALES_PROJECT_DETAIL', id: ownProps.match.params.id })
    }
}


export default connect(mapStateToProps, mapDispatchToProps)(SalesProjectDetail);

我注意到在我使用 Redux (Redux Saga) 帮助我的 API 调用和加载屏幕之后发生了滞后。但是,由于我的 mapStateToProps 都是必要的存储状态,我没有看到任何不必要的重新渲染,并且希望获得一些关于如何继续的建议,当我在选项卡之间切换时它会滞后,并且选项卡中的子组件不会使用任何 Redux 调度,也不使用任何 mapStateToProps,因为它们在子组件中使用的数据是作为来自父组件的 props 发送的(上面显示的那个 -> 执行调度以从 api 获取数据的那个)。

感谢所有帮助,我知道我的问题可能有点含糊,但我真的不知道是什么导致了这种滞后,希望我能在这里得到一些帮助,或者指出我正确的方向,谢谢大家!

4

0 回答 0