You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

next-redux-wrapper中Wrapper.getStaticProps无法正常获取数据问题咨询

Why getStaticProps Fails but getServerSideProps Works (and How to Fix It)

Let's break down the core issue first:
getServerSideProps runs on every user request, so it has access to a full, real HTTP request context (the req object contains all the client's request details). That's why your API call works perfectly here.

On the other hand, getStaticProps runs during the Next.js build phase. At this point, there's no actual user request—so the req object is either incomplete (like missing a valid origin for your API URL) or doesn't exist at all. Your getRooms action relies on absoluteUrl(req) to build the API link, which fails during build because that req isn't a real client request.

Additionally, if your page uses dynamic parameters (like page, location, etc. from the query string), getStaticProps needs a companion getStaticPaths function to define which paths to pre-render during build. Without it, Next.js can't generate the necessary static pages for those dynamic values.


Fix 1: Stop relying on req for your API URL

Instead of trying to pull the origin from a build-time req, use an environment variable to define your API base URL. This is more reliable and works across both build and request phases.

Step 1: Add an environment variable

Create a .env.local file in your project root:

# For development
NEXT_PUBLIC_API_URL=http://localhost:5000/api
# For production (uncomment and update when deploying)
# NEXT_PUBLIC_API_URL=https://your-production-domain/api

Step 2: Update your Redux action

Remove the req parameter and use the environment variable to build your API link:

export const getRooms = (currentPage = 1, location = '', guests, category) => async (dispatch) => { 
  try { 
    let link = `${process.env.NEXT_PUBLIC_API_URL}/rooms?page=${currentPage}&location=${location}` 
    if (guests) link += `&guestCapacity=${guests}`
    if (category) link += `&category=${category}`
    
    const { data } = await axios.get(link) 
    dispatch({ type: ALL_ROOMS_SUCCESS, payload: data }) 
  } catch (error) { 
    dispatch({ type: ALL_ROOMS_FAIL, payload: error.response.data.message }) 
  } 
}

Step 3: Update your getStaticProps

Now you don't need to pass req anymore, and you can add incremental static regeneration (ISR) to keep your data fresh without rebuilding the entire site:

export const getStaticProps = wrapper.getStaticProps(store => async ({ query }) => { 
  await store.dispatch(getRooms(query.page, query.location, query.guests, query.category))
  
  return {
    revalidate: 60, // Regenerate the page every 60 seconds (adjust as needed)
  }
})

Fix 2: Add getStaticPaths for dynamic routes (if applicable)

If your page uses dynamic routing (e.g., /rooms/[page] or relies on query parameters that change), you need to define which paths to pre-render during build. Add this function to your page:

export const getStaticPaths = async () => {
  // Define common paths you want to pre-render
  // Or fetch all possible values from your API if you have a small dataset
  const paths = [
    { params: { page: '1' } },
    { params: { page: '2' } },
    // Add more paths as needed
  ]

  return {
    paths,
    fallback: 'blocking', // Generate missing paths on first request (no loading state)
    // Or use `fallback: true` if you want a loading state for un-pre-rendered paths
  }
}

Your current reducer only stores the rooms array, but your backend returns additional useful data like roomsCount and resPerPage. Update the reducer to save all these values if you need them in your UI:

export const allRoomsReducer = (
  state = { 
    rooms: [], 
    roomsCount: 0, 
    resPerPage: 0, 
    filteredRoomsCount: 0 
  }, 
  action
) => { 
  switch (action.type) { 
    case ALL_ROOMS_SUCCESS: 
      return { 
        ...state,
        rooms: action.payload.rooms,
        roomsCount: action.payload.roomsCount,
        resPerPage: action.payload.resPerPage,
        filteredRoomsCount: action.payload.filteredRoomsCount
      } 
    case ALL_ROOMS_FAIL: 
      return { ...state, error: action.payload } 
    case CLEAR_ERRORS: 
      return { ...state, error: null } 
    default: 
      return state 
  } 
}

Final Notes

  • Make sure your backend API is accessible during the build phase (if using a local API, keep it running while building; if using a production API, ensure it's live).
  • Incremental Static Regeneration (the revalidate option) is a great middle ground—it lets you keep static page performance while updating data periodically.

内容的提问来源于stack exchange,提问作者Kennedy Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 10:57:30