当路径/位置发生变化时,React组件中的数据不会刷新

发布于 2025-02-03 19:46:34 字数 6124 浏览 2 评论 0 原文

我有一个具有“面包屑头”组件的React应用程序,该组件的数据来自API端点。

我在应用程序内的多个组件中使用面包屑头组件,并基于当前路径/窗口。Location面包屑组件将从API获取数据并通过JSX呈现正确的HTML。

我遇到的问题是,当我导航到不同的路径 /窗口。

这就是面包屑组件的样子:

import React, { useState, useEffect } from 'react';
import API from "../../API";
import { useLocation } from 'react-router-dom';
import { BreadCrumbTitleSection, SubtitleSection, Subtitle } from './breadCrumbHeaderStyle';
import { Breadcrumb } from 'react-bootstrap';

    function BreadCrumbHeader() {
        const location = useLocation();
    
        const [breadCrumbData, setBreadCrumbData] = useState([]);
    
        const getBreadCrumbData = async () => {
            const breadCrumbHeaderResponse = await API.fetchBreadCrumbHeader(location.pathname);
            setBreadCrumbData(breadCrumbHeaderResponse);
        };
    
        useEffect(() => {
            getBreadCrumbData();
        }, []);
    
        return (
            <div>
    
                <BreadCrumbTitleSection backgroundUrl={breadCrumbData.BreadCrumbBgImage}>
                    <div className="container">
                        <div className="row no-gutters">
                            <div className="col-xs-12 col-xl-prefix-1 col-xl-11">
                                <h1 className="h3 text-white">{breadCrumbData.BreadCrumbTitle}</h1>
                                <Breadcrumb>
                                    {breadCrumbData.BreadCrumbLinks.map(breadCrumbLink => (
                                        <Breadcrumb.Item href={breadCrumbLink.LinkUrl} key={breadCrumbLink.Id} active={breadCrumbLink.IsActive}>
                                            {breadCrumbLink.LinkText}
                                            </Breadcrumb.Item>
                                    ))}
                                </Breadcrumb>
                        </div>
                    </div>
                </div>
                </BreadCrumbTitleSection>
                <SubtitleSection>
                    <Subtitle> {breadCrumbData.SubTitle}</Subtitle>
                </SubtitleSection>
         </div>
        );
    }
    export default BreadCrumbHeader;

这是我在其他组件中使用它的一个示例:

import React, { useContext } from 'react';
import { useParams } from "react-router-dom";
import { MenuContext } from '../context/menuContext';
import RenderCmsComponents from '../../components/RenderCmsComponents/';
import BreadCrumbHeader from '../../components/BreadCrumbHeader/';
import { CategorySection, CategoryContainer, CategoryItemCard, CategoryItemCardBody, CategoryItemCardImg, CategoryItemTitle, CategoryRow, AddToCartButton, ProductDescription} from './categoryStyle';

 
function Category() {
    const [categoryItems] = useContext(MenuContext);
    const { id } = useParams();
    const category = categoryItems.find(element => element.CategoryName.toLowerCase() === id.toLowerCase());
    var dynamicProps = [];

    {
        category && category.Products.map(productItem => (

            dynamicProps.push(productItem.ProductOptions.reduce((acc, { OptionName, OptionsAsSnipCartString }, i) => ({
                ...acc,
                [`data-item-custom${i + 1}-name`]: OptionName,
                [`data-item-custom${i + 1}-options`]: OptionsAsSnipCartString
            }), {}))));
    }

    return (
        <div>

            <BreadCrumbHeader /> << HERE IT IS 

        <CategorySection backgroundurl="/images/home-slide-4-1920x800.jpg" fluid>
                <CategoryContainer>
                        <CategoryRow>
                            {category && category.Products.map((productItem, i) => (

                                <CategoryItemCard key={productItem.ProductId}>
                                    <CategoryItemTitle>{productItem.ProductName}</CategoryItemTitle>

                                    <CategoryItemCardBody>
                                        <ProductDescription>{productItem.Description}</ProductDescription>

                                        <div>
                                            <CategoryItemCardImg src={productItem.ProductImageUrl} alt={productItem.ProductName} />
                                        </div>
                                       
                                           
                                    </CategoryItemCardBody>


                                    <AddToCartButton
                                        data-item-id={productItem.ProductId}
                                        data-item-price={productItem.Price}
                                        data-item-url={productItem.ProductUrl}
                                        data-item-description={productItem.Description}
                                        data-item-image={productItem.ProductImageUrl}
                                        data-item-name={productItem.ProductName}
                                        {...dynamicProps[i]}>
                                        ADD TO CART   {productItem.Price}
                                    </AddToCartButton>
         
                                </CategoryItemCard>
                            ))}
                        </CategoryRow>
                </CategoryContainer>
            
         </CategorySection>


            <RenderCmsComponents />
        </div>
    );
}
export default Category;

我在堆栈溢出上找到了这篇文章: 为什么使用效果不在window.location.location.location.location.location.location.location.location.location.location.location.pathname更改?

我认为这可能是解决我需要的方法,但我不完全理解所接受的答案。

有人分解可以成为我如何解决问题的方法,并可能给我一个解释,并可能做一些我可以真正了解钩子如何工作以及如何在我的情况下使用它们的阅读。

I have a react app that has a "Bread Crumb Header" component, the data for this component comes from an API end point.

I use the bread crumb header component inside multiple components within the app, and based on the current path/window.location the bread crumb component will get the data from the API and render the correct HTML via JSX.

The problem I have is when I navigate to different paths / window.location's within the application the bread crumb component data doesn't update.

This is what the bread crumb component looks like:

import React, { useState, useEffect } from 'react';
import API from "../../API";
import { useLocation } from 'react-router-dom';
import { BreadCrumbTitleSection, SubtitleSection, Subtitle } from './breadCrumbHeaderStyle';
import { Breadcrumb } from 'react-bootstrap';

    function BreadCrumbHeader() {
        const location = useLocation();
    
        const [breadCrumbData, setBreadCrumbData] = useState([]);
    
        const getBreadCrumbData = async () => {
            const breadCrumbHeaderResponse = await API.fetchBreadCrumbHeader(location.pathname);
            setBreadCrumbData(breadCrumbHeaderResponse);
        };
    
        useEffect(() => {
            getBreadCrumbData();
        }, []);
    
        return (
            <div>
    
                <BreadCrumbTitleSection backgroundUrl={breadCrumbData.BreadCrumbBgImage}>
                    <div className="container">
                        <div className="row no-gutters">
                            <div className="col-xs-12 col-xl-prefix-1 col-xl-11">
                                <h1 className="h3 text-white">{breadCrumbData.BreadCrumbTitle}</h1>
                                <Breadcrumb>
                                    {breadCrumbData.BreadCrumbLinks.map(breadCrumbLink => (
                                        <Breadcrumb.Item href={breadCrumbLink.LinkUrl} key={breadCrumbLink.Id} active={breadCrumbLink.IsActive}>
                                            {breadCrumbLink.LinkText}
                                            </Breadcrumb.Item>
                                    ))}
                                </Breadcrumb>
                        </div>
                    </div>
                </div>
                </BreadCrumbTitleSection>
                <SubtitleSection>
                    <Subtitle> {breadCrumbData.SubTitle}</Subtitle>
                </SubtitleSection>
         </div>
        );
    }
    export default BreadCrumbHeader;

and this is an example of how I am using it inside other components:

import React, { useContext } from 'react';
import { useParams } from "react-router-dom";
import { MenuContext } from '../context/menuContext';
import RenderCmsComponents from '../../components/RenderCmsComponents/';
import BreadCrumbHeader from '../../components/BreadCrumbHeader/';
import { CategorySection, CategoryContainer, CategoryItemCard, CategoryItemCardBody, CategoryItemCardImg, CategoryItemTitle, CategoryRow, AddToCartButton, ProductDescription} from './categoryStyle';

 
function Category() {
    const [categoryItems] = useContext(MenuContext);
    const { id } = useParams();
    const category = categoryItems.find(element => element.CategoryName.toLowerCase() === id.toLowerCase());
    var dynamicProps = [];

    {
        category && category.Products.map(productItem => (

            dynamicProps.push(productItem.ProductOptions.reduce((acc, { OptionName, OptionsAsSnipCartString }, i) => ({
                ...acc,
                [`data-item-custom${i + 1}-name`]: OptionName,
                [`data-item-custom${i + 1}-options`]: OptionsAsSnipCartString
            }), {}))));
    }

    return (
        <div>

            <BreadCrumbHeader /> << HERE IT IS 

        <CategorySection backgroundurl="/images/home-slide-4-1920x800.jpg" fluid>
                <CategoryContainer>
                        <CategoryRow>
                            {category && category.Products.map((productItem, i) => (

                                <CategoryItemCard key={productItem.ProductId}>
                                    <CategoryItemTitle>{productItem.ProductName}</CategoryItemTitle>

                                    <CategoryItemCardBody>
                                        <ProductDescription>{productItem.Description}</ProductDescription>

                                        <div>
                                            <CategoryItemCardImg src={productItem.ProductImageUrl} alt={productItem.ProductName} />
                                        </div>
                                       
                                           
                                    </CategoryItemCardBody>


                                    <AddToCartButton
                                        data-item-id={productItem.ProductId}
                                        data-item-price={productItem.Price}
                                        data-item-url={productItem.ProductUrl}
                                        data-item-description={productItem.Description}
                                        data-item-image={productItem.ProductImageUrl}
                                        data-item-name={productItem.ProductName}
                                        {...dynamicProps[i]}>
                                        ADD TO CART   {productItem.Price}
                                    </AddToCartButton>
         
                                </CategoryItemCard>
                            ))}
                        </CategoryRow>
                </CategoryContainer>
            
         </CategorySection>


            <RenderCmsComponents />
        </div>
    );
}
export default Category;

I found this post on stack overflow:
Why useEffect doesn't run on window.location.pathname changes?

I think this may be the solution to what I need, but I don't fully understand the accepted answer.

Can someone breakdown to be how I can fix my issue and maybe give me an explanation and possible some reading I can do to really understand how hooks work and how to use them in my situation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凑诗 2025-02-10 19:46:34

似乎您应该每次更改 location.pathname 时重新计算 getBreadcrumbData 。在下面的代码中,我添加了 location.pathname usefeffect 依赖项列表

        const location = useLocation();
    
        const [breadCrumbData, setBreadCrumbData] = useState([]);
    
        const getBreadCrumbData = async () => {
            const breadCrumbHeaderResponse = await API.fetchBreadCrumbHeader(location.pathname);
            setBreadCrumbData(breadCrumbHeaderResponse);
        };
    
        useEffect(() => {
            getBreadCrumbData();
        }, [location.pathname]); // <==== here

It seems that you should re-call getBreadCrumbData every time when location.pathname was changed. In the code below I've added location.pathname to useEffect dependency list

        const location = useLocation();
    
        const [breadCrumbData, setBreadCrumbData] = useState([]);
    
        const getBreadCrumbData = async () => {
            const breadCrumbHeaderResponse = await API.fetchBreadCrumbHeader(location.pathname);
            setBreadCrumbData(breadCrumbHeaderResponse);
        };
    
        useEffect(() => {
            getBreadCrumbData();
        }, [location.pathname]); // <==== here
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文