【问题标题】:Page is constantly redrawn when switching between Next.js / Redux pages在 Next.js / Redux 页面之间切换时页面不断重绘
【发布时间】:2020-06-20 18:01:25
【问题描述】:

我使用翻译来提问,因为我不希望在俄语网站上获得帮助。对不起我的英语。

我在使用 Redux 的必要性方面遇到了问题。我为它重做了我的 HOC 和布局。但是现在,当您浏览页面时,整个区域都会重新绘制。

HOC:

import Router from 'next/router'
import { connect } from 'react-redux';
import React, { Component } from 'react'
import { getAccount as getAccountAction } from 'actions/auth'

export default function (Component) {
    class middleware extends Component.WrappedComponent {

        constructor(props) {
            super(props)

            this.state = {
                token: '',
                check: false
            }
        }

        async componentDidMount() {

            const { getAccount } = this.props

            let my_token = this.props.token ? this.props.token : localStorage.getItem('token');
            await getAccount(my_token) // Get all user information
            if(this.props.isAuth && this.props.profile.role == "admin"){
                this.setState({ check: true });
            }
            else {
                Router.replace('/admin/login')
            }
        }

        render() {
            const { check } = this.state;

            if (check) {
                return (
                    <Component {...this.props} />
                )
            } else { return (<div></div>) }
        }
    }

    const mapState = state => ({
        token: state.auth.token,
        isAuth: state.auth.isAuth,
        profile: state.auth.profile
    })
    const mapDispatch = dispatch => ({
        getAccount: (token) => dispatch(getAccountAction(token))
    })

    return connect(mapState, mapDispatch)(middleware);
}

布局:

import { setAdminMenu as setAdminMenuAction } from 'actions/ui'
import styles from './adminLayout.module.css'
import Link from 'next/link'
import { connect } from 'react-redux';
import React, { Component } from 'react'

export default function (Component) {
    class adminLayout extends Component.WrappedComponent {

        constructor(props) {
            super(props)

            this.state = {
                isLoaded: false,
            }
        }

        async componentDidMount() {
            const { setMenu } = this.props
            if (this.props.menu != []) {
                await setMenu(this.props.token); // function to get a list of categories for a menu
                this.setState({isLoaded: true})
            }
        }

        render() {
            let { isLoaded } = this.state
            let url = "/admin/panel/"

            if (!isLoaded) {
                return (
                    <div> </div>
                )
            }
            else {
                let item_menu = this.props.menu.reduce((res, item) => {
                    if (res.hasOwnProperty(item.category)) res[item.category].push(item);
                    else res[item.category] = [item];
                    return res;
                }, {});
                let res = Object.keys(item_menu)
                return (
                    <div id={styles.workspace} >
                        <div id={styles.header}></div>
                        <div id={styles.article}>

                                <Component {...this.props} />

                        </div>
                        <div id={styles.menu}>
                            {res.map((key, index) => (<ul key={`group_admin_menu_` + index}>
                                {item_menu[key].map(i => (
                                    <li key={`item_admin_menu_` + i.id}><Link href={"", url + i.directory}><a>{i.name}</a></Link></li>
                                ))}</ul>))}
                            <ul>
                                <li><Link href={"", url + 'settings'}><a>Настройки</a></Link></li>
                            </ul>
                        </div>
                        <div id={styles.footer}></div>
                    </div >)
            }
        }
    }

    const mapState = state => ({
        token: state.auth.token,
        menu: state.ui.AdminAPP.Menu,
    })
    const mapDispatch = dispatch => ({
        setMenu: (token) => dispatch(setAdminMenuAction(token))
    })

    return connect(mapState, mapDispatch)(adminLayout);
}

页面示例:

import React, { Component } from 'react'
import Router from 'next/router'

import withAdmin from 'middleware/test_withAdmin'
import Layout from 'middleware/layout/adminLayout'
import { connect } from 'react-redux';

import { setAdminMenu as setAdminMenuAction } from 'actions/ui';

class Panel extends Component {
    async componentDidMount() {

    }
    render() {
        return (
            <div><h1>Statistic</h1></div>
        )
    }
}

const mapState = state => ({
    token: state.auth.token,
    menu: state.ui.AdminAPP.Menu,
})
const mapDispatch = dispatch => ({
    setMenu: (token) => dispatch(setAdminMenuAction(token))
})

export default withAdmin(Layout(connect(mapState, mapDispatch)(Panel)))

//withAdmin - HOC

非常感谢您的帮助...我已经尝试了所有可能的方法。

【问题讨论】:

    标签: redux next.js


    【解决方案1】:

    我遇到了类似的问题,它的“布局”部分会重新渲染,因为它是 Next.js 页面的部分

    Next.js,在页面导航上卸载当前页面并呈现新页面,如果您的布局是重新呈现的页面的一部分。

    我已经通过将布局组件移动到 pages/_app 组件来解决这个问题,该组件是您应用的根组件,并且不会重新安装在页面导航上。

    有关更多信息,您可以阅读此blog post

    【讨论】:

    • 谢谢,我意识到错误不在我想的地方。我将重做我的布局并将其传输到_app。顺便说一句,这将使我免于其他一些困难。
    猜你喜欢
    • 2019-03-17
    • 2021-04-28
    • 2014-09-29
    • 1970-01-01
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    相关资源
    最近更新 更多