shanksu 218
shanksu 218

Reputation: 195

store.getState() returning empty value in index.js

using nextjs for server-side-rendering trying to get the state from redux store in getServerSideProps(). but getting emtpy value.

getting data from redux in client side inside the component with const productList = useSelector(state => state.productList) const { loading, error, products } = productList works fine. but when using getServersideProps() im getting emtpy results.

index.js:

import store from '../redux/store'

export default function Home({products, error, loading}) {

  const dispatch = useDispatch()

  useEffect(() => {
    dispatch(listProducts())
  }, [dispatch])

  return (
    <>
      <Header />
      <Products loading={loading} error={error} products={products} />
      <Footer />
    </>
  )
}

export async function getServerSideProps() {
  const state = store.getState()
  const { loading, error, products } = state.productList

  return {props: {products: products, loading: loading, error: error}}
}

*note: even when i did console.log(store.getState()) inside the component its still returning empy array

reducer:

export const productListReducer = (state = { products: [] }, action) => {
    switch (action.type) {
        case 'PRODUCT_LIST_REQUEST':
            return { loading: true, products: [] }
        case 'PRODUCT_LIST_SUCCESS':
            return { loading: false, products: action.payload }
        case 'PRODUCT_LIST_FAIL':
            return { loading: false, error: action.payload }
        default:
            return state
    }
}

action:

import axios from 'axios'

export const listProducts = () => async (dispatch) => {
    try {
        dispatch({ type: 'PRODUCT_LIST_REQUEST' })

        const { data } = await axios.get('/api/products')

        dispatch({
            type: 'PRODUCT_LIST_SUCCESS',
            payload: data
        })
    } catch (error) {
        dispatch({
            type: 'PRODUCT_LIST_FAIL',
            payload: error.response && error.response.data.message
                ? error.response.data.message : error.message
        })
    }
}

store.js:

const reducer = combineReducers({
    productList: productListReducer,
    categoryList: categoryListReducer,
})

const initialState = {}

const middleware = [thunk]

const store = createStore(
    reducer, initialState, composeWithDevTools(applyMiddleware(...middleware))
)

export default store

Upvotes: 3

Views: 1539

Answers (2)

Ganesh Mohanty
Ganesh Mohanty

Reputation: 289

try invoking getState() directly and don't forget to pass it as argument and also make sure you have passed the store to your app component

export async function getServerSideProps(getState) {
  const state = getState()
  const { loading, error, products } = state.productList

  return {props: {products: products, loading: loading, error: error}}
}

Upvotes: 2

Daly
Daly

Reputation: 879

The issue is useDispatch is a React-Redux function, but the store has not been connected to the React components.

Instead of useDispatch try store.dispatch instead:

import store from '../redux/store'

export default function Home({products, error, loading}) {

  useEffect(() => {
    store.dispatch(listProducts())
  })

  return (
    <>
      ...
    </>
  )
}

Note, the array passed to useEffect controls when that effect is run, so it would not make sense to pass in the dispatch function. See this post for more details.

You could also connect the Redux store to the React components using React-Redux and keep using useDispatch.

Upvotes: -1

Related Questions