reactjs 当我在React Router Dom中使用两个参数并直接在页面上导航时,数据获取不会发生

0wi1tuuw  于 2023-05-28  发布在  React
关注(0)|答案(1)|浏览(70)

我遇到了一个非常奇怪和复杂的React Router问题。我正在尝试实现一个单页应用程序,它的页面数量取决于json文件中产品的数量。在我的应用程序中,我的主页总是只包含一个页面,因此它只有一个参数,称为:节。我遇到的这个bug只有在我使用第二个参数page_number时才会发生,所有其他页面都有这个参数。
这是我的主要组成部分,包含各种网页,并取决于路由器参数

import { Routes, Route } from 'react-router-dom';
import GoodsList from './GoodsList';
import Pages from './Pages';

function Sections() {
    return (
        <Routes>
            <Route path='' element={<>
                <div className="pageContent" data-main="true">
                    <p>Novelties</p>
                    <GoodsList goods="novelties" />
                    <p>Hot</p>
                    <GoodsList goods="hot" />
                </div>
            </>} />
            <Route path='/:section/:page_number' element={<>
                <div className='pageContent'>
                    <GoodsList />
                    <Pages />
                </div>
            </>} />
        </Routes>
    )

这个组件我用来在页面上导航

import { Link } from 'react-router-dom';

function Menu() {
    return (
        <nav className='menu'>
            <ul>
                <li>
                    <Link to="">Main</Link>
                </li>
                <li>
                    <Link to="figures/1">Figures</Link>
                </li>
                <li>
                    <Link to="dakimakuras/1">Figures</Link>
                </li>
                <li>
                    <Link to="manga/1">Manga</Link>
                </li>
                <li>
                    <Link to="other/1">Other merch</Link>
                </li>
            </ul>
        </nav>
    )
}

最后,该组件显示产品列表

import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { fetchProducts } from '../redux/fetchDataReducer';
import { useParams } from 'react-router-dom';

function GoodsList(props) {
    const params = useParams();
    const goods = returnGoods();
    function returnGoods() {
        if (document.location.pathname == "/") {
            return props.goods
        }
        return params.section
    }
    
    const dispatch = useDispatch();
    useEffect(() => {
        dispatch(fetchProducts());
    }, [])
    
    const products = useSelector(state => state.fetchDataReducer.products);
    
    return (
        <div className="list">
            {products && products[goods].map((good, i) => (
                <div className="productCard" key={i}>
                    <div className="productPicture">
                        <img src={good.pic} alt="ERROR" />
                    </div>
                    <p className="productName">{good.name}</p>
                </div>
            ))}
        </div>
    )
}

问题是,当我点击导航栏中的主页或通过在地址栏中键入路径直接移动到它时,它总是工作正常。然后,如果我点击导航栏中的任何部分,一切工作正常,但如果我试图刷新页面或移动到任何页面,除了主要的直接输入其地址在酒吧的GoodsList组件不会加载产品列表。数据的获取不会以某种方式发生,但组件本身和地址栏中的所有参数都将被加载。但如果我将再次移动到主页,然后通过使用导航链接到任何其他部分,它将再次加载良好,问题不会出现,直到我刷新页面。
因此,只有当我有:page_number参数时才会出现问题,并且只影响我通过Redux从json文件接收的数据。如果我删除第二个参数,bug就不会发生。当我直接移动到带有此参数的任何部分或刷新页面时,如果我在菜单栏上使用导航链接,它会正常工作,但只有当我在此之前访问过主页时才会发生。
UPD。添加页面组件

import { useSelector } from "react-redux";
import { Link, useParams } from 'react-router-dom';

function Pages() {
    const params = useParams();
    const products = useSelector(state => state.fetchDataReducer.products);
    const currentProduct = products ? products[params.section] : [];
    const pageLinks = [];

    let numberOfPages = () => {
        if ((currentProduct.length / 8) % 1 == 0) {
            return currentProduct.length / 8
        }
        else return Math.floor((currentProduct.length / 8) + 1)
    }

    for (let x = 1; x < (numberOfPages() + 1); x++) {
        pageLinks.push(<Link to={`/${params.section}/${x}`} className="pageLink" key={x}>{x}</Link>);
    }
    
    return (
        <div className="pageList">
            {pageLinks}
        </div>
    )
}

UPD. Codesandbox示例https://codesandbox.io/p/github/TheDanieLSh/React-Sites/draft/modest-hopper?layout=%257B%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522panelType%2522%253A%2522TABS%2522%252C%2522id%2522%253A%2522cli1ipbjf00iu356lorpxfmbk%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522cli1ipbjf00iu356lorpxfmbk%2522%253A%257B%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522cli1ipbje00it356lhcqi48gt%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252F.gitignore%2522%257D%255D%252C%2522id%2522%253A%2522cli1ipbjf00iu356lorpxfmbk%2522%252C%2522activeTabId%2522%253A%2522cli1ipbje00it356lhcqi48gt%2522%257D%257D%252C%2522showDevtools%2522%253Atrue%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D

5w9g7ksd

5w9g7ksd1#

fetchProducts操作正在使用从"/public"目录中获取/加载的products.json文件的***相对***资源路径。

fetch("products.json")

当应用程序当前位于根"/"路由上时,当它调度fetchProducts时呈现GoodsList组件时,这可以正常工作,并且符合预期。products.json资源被请求***相对于当前URL路径,例如"/products.json",并且数据被加载到Redux存储中而没有问题。
在导航到子路线时,例如,"/:section/:page_number",现在请求products.json文件相对于 * 该 * 路径,例如"/figures/1/products",公共目录中不存在。当用户在子路由上并重新加载页面时,获取失败。只要用户至少( 最终 )登陆到主"/"页面,那么当请求发出时,它实际上成功了,这就很好。
要解决这个问题,您只需指定"/products.json"
绝对***资源路径。

fetch("/products.json")
export const fetchProducts = createAsyncThunk(
  "dataFetch/fetchProducts",
  async () => {
    const response = await fetch("/products.json");
    const data = await response.json();
    return data;
  }
);

相关问题