首页 > 解决方案 > 在 Next.js / Redux 页面之间切换时页面不断重绘

问题描述

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

我在使用 Redux 的必要性方面遇到了问题。我为它重做了我的 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

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

标签: reduxnext.js

解决方案


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

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

我已经通过将布局组件移动到作为pages/_app应用程序根组件的组件来解决它,并且不会重新安装在页面导航上。

有关更多信息,您可以阅读此博客文章


推荐阅读