Path/Location 更改时 React 组件中的数据不刷新
Data in React Component Not refreshing when Path/Location changes
我有一个带有“面包屑 Header”组件的 React 应用程序,该组件的数据来自 API 端点。
我在应用程序的多个组件中使用面包屑 header 组件,并且基于当前 path/window.location,面包屑组件将从 API 获取数据并通过 JSX 呈现正确的 HTML。
我遇到的问题是,当我导航到应用程序中的不同 paths/window.location 时,面包屑组件数据没有更新。
这是面包屑组件的样子:
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-preffix-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;
我在堆栈溢出时发现了这个 post:
我认为这可能是我需要的解决方案,但我不完全理解接受的答案。
谁能告诉我如何解决我的问题,也许可以给我一个解释,并可能给我一些阅读,以真正了解挂钩的工作原理以及如何在我的情况下使用它们。
似乎每次 location.pathname
更改时,您都应该 re-call getBreadCrumbData
。在下面的代码中,我将 location.pathname
添加到 useEffect
依赖列表
const location = useLocation();
const [breadCrumbData, setBreadCrumbData] = useState([]);
const getBreadCrumbData = async () => {
const breadCrumbHeaderResponse = await API.fetchBreadCrumbHeader(location.pathname);
setBreadCrumbData(breadCrumbHeaderResponse);
};
useEffect(() => {
getBreadCrumbData();
}, [location.pathname]); // <==== here
我有一个带有“面包屑 Header”组件的 React 应用程序,该组件的数据来自 API 端点。
我在应用程序的多个组件中使用面包屑 header 组件,并且基于当前 path/window.location,面包屑组件将从 API 获取数据并通过 JSX 呈现正确的 HTML。
我遇到的问题是,当我导航到应用程序中的不同 paths/window.location 时,面包屑组件数据没有更新。
这是面包屑组件的样子:
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-preffix-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;
我在堆栈溢出时发现了这个 post:
我认为这可能是我需要的解决方案,但我不完全理解接受的答案。
谁能告诉我如何解决我的问题,也许可以给我一个解释,并可能给我一些阅读,以真正了解挂钩的工作原理以及如何在我的情况下使用它们。
似乎每次 location.pathname
更改时,您都应该 re-call getBreadCrumbData
。在下面的代码中,我将 location.pathname
添加到 useEffect
依赖列表
const location = useLocation();
const [breadCrumbData, setBreadCrumbData] = useState([]);
const getBreadCrumbData = async () => {
const breadCrumbHeaderResponse = await API.fetchBreadCrumbHeader(location.pathname);
setBreadCrumbData(breadCrumbHeaderResponse);
};
useEffect(() => {
getBreadCrumbData();
}, [location.pathname]); // <==== here