【问题标题】:reactjs breadcrumbs function and too many rendersreactjs面包屑功能和太多渲染
【发布时间】:2020-09-02 14:22:42
【问题描述】:

我正在尝试为我的 reactjs 项目构建一个面包屑组件,但我不断收到Too many re-renders 的错误。我的App.jsx 看起来像这样:

<div className="page-subheader">
    <Breadcrumbs />
</div>

Routes.jsx 看起来像这样:

export default [
    {
        name: 'Department1',
        abbrev: 'D1',
        icon: "fas fa-bullhorn",
        rootpath: '/dept1',
        paths: [
            {
                path: "/dept1",
                name: "Dashboard",
                Component: Dashboard,
                icon: "icon-Gaugage",
                showWelcome: true,
                crumbs: [
                    {name: 'Home', path: '/'},
                    {name: 'Department1', path: '/dept1'},
                ],
            },
            {
                path: "/dept1/mailroom",
                name: "Mailroom",
                Component: Mailroom,
                icon: "fas fa-envelope",
                showWelcome: false,
                crumbs: [
                    {name: 'Home', path: '/'},
                    {name: 'Department1', path: '/dept1'},
                    {name: 'Campaigns', path: '/dept1/mailoom'},
                ],
            },
            {
                path: "/dept1/people",
                name: "People",
                Component: People,
                icon: "fas fa-users",
                showWelcome: false,
                crumbs: [
                    {name: 'Home', path: '/'},
                    {name: 'Department1', path: '/dept1'},
                    {name: 'People', path: '/dept1/people'},
                ],
            },
            {
                path: "/dept1/tools",
                name: "Tools",
                Component: Tools,
                icon: "fas fa-chart-bar",
                showWelcome: true,
                crumbs: [
                    {name: 'Home', path: '/'},
                    {name: 'Department1', path: '/dept1'},
                    {name: 'Tools', path: '/dept1/tools'},
                ],
            }
        ],
    },
    {
        name: 'Department2',
        icon: "fas fa-building",
        abbrev: 'D2',
        rootpath: '/dept2',
        paths: [],
    },
    {
        name: 'Deaprtment3',
        icon: "fas fa-users-cog",
        abbrev: 'D3',
        rootpath: '/dept3',
        paths: [],
    }
];

那么Breadcrumbs.jsx 看起来像

import React, {useState} from "react";
import { NavLink } from "react-router-dom";
import { useLocation } from 'react-router-dom'
import Routes from "../Utilities/Routes";


const Breadcrumbs = (props) => {
    let location = useLocation();

    const [currentPath, setCurrentPath] = useState(location.pathname);
    
    // going to default to the comms root for now
    const [currentRouteObject, setCurrentRouteObject] = useState({
        path: "/dept1",
        name: "Dashboard",
        Component: Dashboard,
        icon: "icon-Gaugage",
        showWelcome: true,
        crumbs: [
            {name: 'Home', path: '/'},
            {name: 'Department1', path: '/dept1'},
        ],
    });

    Routes.map((route, key) => {
        if (currentPath.includes(route.rootpath)) {
            route.paths.map((routepath, routekey) => {
                if (currentPath.includes(routepath.path)) {
                    setCurrentRouteObject(routepath);
                    return true;
                }
            })
        }
    });

    return (
        <>
        <div className="container-fluid">
            <div className="row align-items-center">
                <div className="crumbs">
                    <nav aria-label="breadcrumb">
                        <ol className="breadcrumb">
                            <li className="breadcrumb-item"><NavLink to="/"><i className="icon-Home mr-2 fs14" /></NavLink></li>
                            {currentRouteObject.crumbs.map(({ name, path }, key) =>
                                key + 1 === currentRouteObject.crumbs.length ? (
                                        <li key={key} className="breadcrumb-item">{name}</li>
                                ) : (
                                    <li className="breadcrumb-item active"><NavLink key={key} to={path}>{name}</NavLink></li>
                                )
                            )}
                        </ol>
                    </nav>
                </div>
            </div>
        </div>
        </>
    );
};

export default Breadcrumbs;

我是新手,但这一切似乎都很简单——我不明白为什么它会一遍又一遍地重新渲染面包屑组件。

【问题讨论】:

  • 首先,不要在.map 方法中设置状态。创建您的最终对象,然后将该对象设置为您的状态。

标签: javascript reactjs twitter-bootstrap


【解决方案1】:

React 钩子是“普通”的 JS 函数(理解这一点很重要)。每次状态发生变化时,react 都会调用该函数。

问题:

面包屑组件一个“反应钩子”。函数从上到下执行,setCurrentRouteObject(routepath)改变状态。因为状态改变了,又调用了Breadcrumbs,所以状态又改变了,所以又调用了Breadcrumbs,...

解决办法:

您应该使用useEffect() 根据其他状态更改状态。

useEffect( function(){
    // ...
    setCurrentRouteObject(/* ... */);
}, [ currentPath ] );

您在这里使用Routes 的方式似乎有问题,我不太明白会发生什么。您可能想看看.find() 方法。

【讨论】:

    猜你喜欢
    • 2019-01-31
    • 1970-01-01
    • 2016-06-22
    • 2022-01-12
    • 1970-01-01
    • 2017-03-20
    • 2016-05-06
    • 2020-09-17
    • 2020-08-07
    相关资源
    最近更新 更多