У меня ошибка 404 не найдена при обновлении страницы с динамическими маршрутами ini next js, моя страница структуры выглядит следующим образом:
pages
[storeName]
summaries.jsx
[store-insight].jsx
когда я нахожусь в [store-insight].jsx
, мне нужен запрос в URL-адресе, который будет использоваться для обращения к API. например www.url.com/storName/10
, я использую 10
в теле API.
*Примечание: когда я обновляю страницу из localhost
, все в порядке.
вот код в [store-insight].jsx
:
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import { BackButton } from '../../components/button/BackButton';
import Navbar from '../../components/Navbar';
import { useSelector } from 'react-redux';
import { StoreInsightHeader } from '../../components/storeInsight/StoreInsightHeader';
import { KeyValueInsight } from '../../components/storeInsight/KeyValueInsight';
import { StoreInsightSummaryChart } from '../../components/storeInsight/StoreInsightSummaryChart';
const StoreInsight = () => {
const { back, query } = useRouter();
const router = useRouter();
const {
store,
filterReport,
revenuInsight,
featuresInsight,
productInsight,
browsingInsight,
operationalGraph,
} = useSelector((store) => store);
// const { detailStore } = store;
// const { name, country_code, location } = detailStore;
const [storeDetail, setStoreDetail] = useState({});
const storeDetails = () => {
const splitted = query['store-insight']?.split('&');
setStoreDetail((prev) => {
return {
...prev,
id: splitted[0],
storeName: splitted[1],
storeLocation: splitted[2],
storeLogo: splitted[3],
};
});
};
useEffect(() => {
if (query['store-insight']?.length > 0) storeDetails();
}, [query, storeDetail?.id]);
return (
<>
<div className='bg-white'>
<Navbar storeLogo = {storeDetail?.storeLogo} />
</div>
<div className='m-6 flex flex-1 flex-row items-center space-x-3'>
<BackButton
onClick = {() => {
router.push({
pathname: `/${query?.storeName}/summaries`,
query: { date: filterReport?.filter },
});
localStorage.removeItem('storeDetail');
}}
className = {'h-3 w-3'}
/>
<label className='text-[10px] font-bold'>
Back to Account Level Insights
</label>
</div>
<div className='bg-white p-4 rounded-lg mx-4'>
<StoreInsightHeader
storeName = {`${storeDetail?.storeName} ${storeDetail?.storeLocation}`}
/>
<KeyValueInsight />
<StoreInsightSummaryChart />
</div>
</>
);
};
export default StoreInsight;
также используется на странице <KeyValueInsight />
компонента ini [store-insight].jsx
, как показано ниже:
import { useRouter } from 'next/router';
import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import {
setKeyInsight,
setValueCreated,
} from '../../features/InsightV2/storeMetricSlice';
import { key_value_insight } from '../../resource/dummy-data';
import { getStoreMetric } from '../../services/insightV2/storeMetric';
import { KeyValueInsightCard } from '../card/KeyValueInsightCard';
import BrowsingInterestSkeleton from '../skeleton/BrowsingInterest';
import { convertInputPrice } from '../../helper/priceConverter';
export const KeyValueInsight = () => {
const { query } = useRouter();
const dispatch = useDispatch();
const { store, filterReport, storeMetric } = useSelector((store) => store);
const { filter, custom_date } = filterReport;
const { key_insight, value_created } = storeMetric;
const [loading, setLoading] = useState(false);
const [storeDetail, setStoreDetail] = useState({});
const storeDetails = () => {
const splitted = query['store-insight']?.length && query['store-insight']?.split('&');
setStoreDetail((prev) => {
return {
...prev,
id: splitted[0],
storeName: splitted[1],
storeLocation: splitted[2],
storeLogo: splitted[3],
};
});
};
const currency = () => {
if (storeDetail?.storeName === 'al-ikhsan') {
return `MYR`;
} else {
return `SGD`;
}
};
const fetchData = async () => {
try {
setLoading(true);
if (filter === 'custom') {
const { data } = await getStoreMetric({
days: filter,
storeId: storeDetail?.id,
customStart: custom_date?.custom_start,
customeEnd: custom_date?.custom_end,
});
if (data) {
dispatch(setKeyInsight(data?.key_insight));
dispatch(setValueCreated(data?.value_created));
}
} else {
const { data } = await getStoreMetric({
days: filter,
storeId: storeDetail?.id,
});
if (data) {
dispatch(setKeyInsight(data?.key_insight));
dispatch(setValueCreated(data?.value_created));
}
}
} catch (error) {
console.info('store metric chart log <<<<<<', error);
} finally {
setLoading(false);
}
};
useEffect(() => {
if (query['store-insight']?.length > 0) storeDetails();
}, [query]);
useEffect(() => {
if (storeDetail?.id) fetchData();
}, [storeDetail?.id, filter, custom_date]);
return (
<div className='grid grid-cols-2 mt-4 gap-x-4'>
<div className='p-4 rounded-lg border'>
<div className='font-semibold text-xs mb-4'>Key Insights</div>
{loading ? (
<BrowsingInterestSkeleton />
) : (
<div className='grid text-center grid-cols-4 gap-x-4'>
<KeyValueInsightCard
title = {'Capture'}
value = {key_insight?.capture?.value || 'WIP'}
/>
<KeyValueInsightCard
title = {'Browsing'}
value = {key_insight?.browsing?.value || 'WIP'}
/>
<KeyValueInsightCard
title = {'Leads'}
value = {key_insight?.leads?.value || 'WIP'}
/>
<KeyValueInsightCard
title = {'Conversion'}
value = {key_insight?.conversion?.value || 'WIP'}
/>
</div>
)}
</div>
<div className='p-4 rounded-lg border'>
<div className='font-semibold text-xs mb-4'>Value Created</div>
{loading ? (
<BrowsingInterestSkeleton />
) : (
<div className='grid text-center grid-cols-4 gap-x-4'>
<KeyValueInsightCard
title = {'Shoppers Served'}
value = {
convertInputPrice(`${value_created?.shoppers_served?.value}`) ||
'WIP'
}
/>
<KeyValueInsightCard
title = {'Time Saved'}
value = {
convertInputPrice(`${value_created?.time_saved?.value}`) +
` min`
}
/>
<KeyValueInsightCard
title = {'Shoppers Acquired'}
value = {value_created?.shoppers_acquired?.value || 'WIP'}
/>
<KeyValueInsightCard
title = {'Sales Generated'}
value = {
`${currency()} ${parseFloat(
value_created?.sales_generated?.value,
).toFixed()}.00` || 'WIP'
}
/>
</div>
)}
</div>
</div>
);
};
Я нашел решение своей проблемы, возможно, кто-нибудь, у кого возникла такая же ошибка, может попробовать это решение. Я переименовал [store-insight].jsx
в [storeinsight].jsx
, и это сработало. Я думаю, что next не позволяет иметь -
на динамической странице.