Comments (35)
In my case it turns out I wasn't returning the promise in my chain of dispatch functions. Working perfectly now!
For anyone else running into the same problem, here's an example:
Component — using async/await
static async getInitialProps({ store, query: { id } }) {
await store.dispatch(loadQuoteIfNeeded(id))
return { id }
}
Actions — note that loadQuoteIfNeeded()
has an implicit return and getQuote()
is being returned
export const initiateLoadQuote = quoteId => (dispatch) => {
dispatch(loadQuote(quoteId))
return getQuote(quoteId)
.then(({ data: quotes }) => {
if (quotes === null) Router.push('/')
dispatch(loadQuoteSuccess(quotes, quoteId))
})
.catch((err) => {
dispatch(loadQuoteError(quoteId))
logAjaxError('initiateLoadQuote', err)
})
}
export const loadQuoteIfNeeded = quoteId => (dispatch, getState) => (
shouldLoadQuote(getState(), quoteId) ? dispatch(initiateLoadQuote(quoteId)) : null
)
from next-redux-wrapper.
I have same issue, im using nextjs + redux toolkit I got the updated store on server, but i didnt get the store on client up to date like on server
static async getInitialProps(ctx) {
if (ctx.isServer) {
if (ctx.store.getState().users.categories.length === 0) {
const res = await ctx.store.dispatch(users.usersSlice.actions.getCategories());
console.log(ctx.store.getState());
// that console.log return the new state of redux server store
}
} else {
console.log('ctx', ctx.store.getState());
}
return {}
}
Action
getCategories: () => async dispatch => {
dispatch(categoriesReset());
try {
dispatch(signupLoading());
const res = await axios.get(`/api/v1/users/categories`);
dispatch(categoriesSucces(res.data));
return res.data;
} catch (err) {
dispatch(categoriesError(err.response.data));
return err;
}
}
Store
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
import rootReducers from "./rootReducers";
const initStoreSSR = {
users: {
data: {},
status: 0,
token: "",
message: '',
categories: []
}
};
export const initStore = (preloadedState = {}) => {
return configureStore({
reducer: rootReducers,
preloadedState: { ...preloadedState, ...initStoreSSR },
middleware: [...getDefaultMiddleware()]
});
};
from next-redux-wrapper.
@brunoqs Looks like you’re overwriting your preloaded state with default state:
preloadedState: { ...preloadedState, ...initStoreSSR },
You need to change the order.
from next-redux-wrapper.
I can't help with MobX. Regarding redux you MUST explicitly tell NextJS to await
until all actions are dispatched: https://github.com/kirill-konshin/next-redux-wrapper#async-actions-in-getinitialprops
Pay close attention that you won't have any unhandled promises that were created inside the action.
from next-redux-wrapper.
@kirill-konshin Thank you for response. I'm using version 6. I handled the Hydrate action. This solved my problem.
import { HYDRATE } from 'next-redux-wrapper';
const authReducer = (state = {}, action) => {
switch (action.type) {
case HYDRATE:
return {...state, ...action.payload.authReducer};
case 'authenticate':
return { ...state, token: action.payload };
case 'deauthenticate':
return { ...state, token: null };
case 'getUser':
return { ...state, user: action.payload };
default:
return state;
}
};
export default authReducer
from next-redux-wrapper.
@msefer just follow the example: https://github.com/kirill-konshin/next-redux-wrapper#usage
import {createStore} from 'redux';
// create a makeStore function
const makeStore = (context) => createStore(reducer);
from next-redux-wrapper.
function getInitialProps = async ({store}) => {
await postRequest(store);
}
without await
you will create a detached promise chain which will be executed in parallel and won't affect the resulting state that will be transferred to client before postRequest
will finish. Also as a side note, you can't use store anywhere outside Next.js lifecycle hooks and/or components.
from next-redux-wrapper.
@jamal-rahimzadegan create an action and use something like redux-thunk
or redux-promise-middleware
to dispatch it.
from next-redux-wrapper.
@jamal-rahimzadegan https://github.com/kirill-konshin/next-redux-wrapper/blob/types-enchancements/packages/demo-saga/src/components/saga.tsx
from next-redux-wrapper.
https://github.com/vercel/next.js/tree/canary/examples/with-redux-wrapper follow this example.
https://github.com/vercel/next.js/blob/canary/examples/with-redux-wrapper/store/store.js
This configuration saves me.
from next-redux-wrapper.
For reference, here's what I have elsewhere:
quote.js
export default reduxPage(connect(mapStateToProps, connectedActions)(Quote))
redux.js
import withRedux from 'next-redux-wrapper'
import { applyMiddleware, createStore } from 'redux'
import { composeWithDevTools } from 'redux-devtools-extension/developmentOnly'
import thunk from 'redux-thunk'
import rootReducer from './modules'
const initStore = (initialState = {}) => {
const middleware = composeWithDevTools(applyMiddleware(thunk))
return createStore(rootReducer, initialState, middleware)
}
const reduxPage = page => withRedux(initStore)(page)
export default reduxPage
rootReducer.js
import { combineReducers } from 'redux'
import appReducer from '../modules/app'
import dataReducer from '../modules/data'
import uiReducer from '../modules/ui'
const rootReducer = combineReducers({
app: appReducer,
data: dataReducer,
ui: uiReducer,
})
export default rootReducer
from next-redux-wrapper.
I meet similar problem, Reducer has already update in server. But front-page do not received any update.
I use with saga to do very basic async loading.
from next-redux-wrapper.
Can you look at the snapshot state delivered from the server? If it's correct but UI keeps loading things — you need to add conditions in getInitialProps
to load only needed things. If server state is incorrect/not full — you probably missed async loading of something.
from next-redux-wrapper.
This is a very wide-spread issue... unfortunately library has nothing to do with it. But, if you use Bluebird, it will tell you that there is a lost promise.
from next-redux-wrapper.
Same issue :(
from next-redux-wrapper.
@phumaster can you describe your issue? The one in the topic was a lost promise, do you have it as well?
from next-redux-wrapper.
@phumaster Have you referred to my solution to the problem to see if it solved it for you?
from next-redux-wrapper.
Hi, thank for the response. When I dispatch an action. The NextJS render but not wait for action resolve. Then, I switch to use MobX. It's well. Now, MobX render object from the server like pic 1
And client side object is not plain javascript.
Should I create issue? Sorry for my english.
from next-redux-wrapper.
@kirill-konshin Thank you. I think, My problem with Redux is created new a promise when action dispatch. I will try it again.
from next-redux-wrapper.
I'm using redux saga and facing the same issue as @jabacchetta was facing. Everything is perfect till my reducer but my store's state is note updated. Anyone ?
from next-redux-wrapper.
Can you provide the repo to reproduce?
from next-redux-wrapper.
@kirill-konshin I solved it with componentDidMount
in _app.js. As it runs on the client side and will work perfectly.
from next-redux-wrapper.
@kirill-konshin thx a lot dude, u saved my friday
from next-redux-wrapper.
@brunoqs you're most welcome.
from next-redux-wrapper.
I've same issue. Store not updating.
Store.js
import thunk from 'redux-thunk';
import rootReducer from "../redux/reducers/rootReducer";
import {createStore, applyMiddleware, combineReducers, compose} from 'redux';
const composeEnhancer = typeof window == 'object' &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ &&
process.env.NODE_ENV !== "production" ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const store = createStore(rootReducer, composeEnhancer(applyMiddleware(thunk)));
export default store;
_app.js
import App from 'next/app'
import React from "react";
import store from '../redux/store';
import { Provider } from 'react-redux';
import withRedux from "next-redux-wrapper";
import { appWithTranslation } from '../i18n';
import 'bootstrap/dist/css/bootstrap.min.css';
import Layout from '../components/Layout/Layout';
function AppPage({ Component, pageProps }) {
return (
<>
<Provider store={store}>
<Layout>
<Component {...pageProps} />
</Layout>
</Provider>
</>
)
}
AppPage.getInitialProps = async (appContext) => {
const appProps = await App.getInitialProps(appContext);
return { ...appProps }
};
// makeStore function that returns a new store for every request
const makeStore = () => store;
// withRedux wrapper that passes the store to the App Component
export default withRedux(makeStore)(appWithTranslation(AppPage));
index.js
import api from "../api";
import Head from 'next/head'
import Home from '../components/Home/Index';
import { parseCookies } from '../lib/parseCookies';
import { authenticate } from "../redux/actions/authActions";
function HomePage({ user }) {
return (
<>
<Head>
<title>Anasayfa</title>
</Head>
<Home />
</>
)
}
HomePage.getInitialProps = async (ctx) => {
const { store } = ctx;
const cookies = parseCookies(ctx.req);
const data = "Bearer " + cookies.token;
const response = await api.getUser(data);
store.dispatch({ type: "authenticate", payload: "testToken" });
console.log(store.getState().authReducer.token);
return { user: response ? response.data : null };
};
export default HomePage
rootReducer.js
import { combineReducers } from "redux";
import authReducer from './authReducer';
const rootReducer = combineReducers({
authReducer
});
export default rootReducer
authReducer.js
const authReducer = (state = {}, action) => {
switch (action.type) {
case 'authenticate':
return { ...state, token: action.payload };
case 'deauthenticate':
return { ...state, token: null };
case 'getUser':
return { ...state, user: action.payload };
default:
return state;
}
};
export default authReducer
from next-redux-wrapper.
@msefer if you are using version 6 you must handle the HYDRATE
action.
If you are on version 5 it looks like you always use one store instead of a createStore
function that accepts initialState
.
Your usage is something really odd. It does not follow the guidelines.
from next-redux-wrapper.
@msefer great! But still you should not export default store. You need to create it dynamically...
// makeStore function that returns a new store for every request
const makeStore = () => store;
Your code does exactly the opposite from what comment suggests.
Also I suggest to start using createWrapper
instead of import withRedux from "next-redux-wrapper";
. This is deprecated.
from next-redux-wrapper.
@kirill-konshin How can I create the store dynamically?
I'm start using createWrapper instead of withRedux. In this way:
export default createWrapper(makeStore)(appWithTranslation(AppPage));
from next-redux-wrapper.
I have a similar problem, I can update store form getInitialProps and inside the components, but not in an independent function
export function postRequest() {
return new Promise((resolve, reject) => {
let store=STORE()
**store.dispatch({ type: 'SET_TOKEN', payload: { token:'passed token' } });**
axios
.post(URL, params || {}, headers(token))
.then((response) => {
resolve(response);
})
.catch((error) => {
})
.finally(() => {});
})
from next-redux-wrapper.
@jamal-rahimzadegan do you await
for this function in the executor?
from next-redux-wrapper.
@jamal-rahimzadegan do you
await
for this function in the executor?
what do you mean?
its a function outside of component
from next-redux-wrapper.
@kirill-konshin
thank you for your fast response.
I want to create a reusable Axios request function that dispatches
how could I achieve this?
from next-redux-wrapper.
@kirill-konshin
I'm using redux-saga could you give me some link or any advice for this?
from next-redux-wrapper.
how to use HYDRATE with redux-toolkit createReducer?
const userReducer = createReducer(initialState, {
[HYDRATE]: (state, action) => {
state = { ...state, ...action.payload.userReducer };
},
Is it wrong?
from next-redux-wrapper.
how to use HYDRATE with redux-toolkit createReducer?
const userReducer = createReducer(initialState, { [HYDRATE]: (state, action) => { state = { ...state, ...action.payload.userReducer }; },
Is it wrong?
from next-redux-wrapper.
Related Issues (20)
- Meaning of the hydrating flag in the new version HOT 3
- Next 13 with next-redux-wrapper HOT 13
- Possible documentation bug.
- Internal Hooks are broken with Next 13 and React 18 HOT 4
- Two initialState passed to client when using _app.tsx + getServerSideProps HOT 1
- NextRouter was not mounted when using next-redux-wrapper HOT 7
- impact on performance when store rerenders on every request. HOT 1
- State value reset between page transitions in Next.js with Redux Toolkit and Next Redux Wrapper HOT 1
- parameter 'context' is empty for makeStore function
- Redux Toolkit example is unclear
- Breaking change from `[email protected]`: Error: `builder.addCase` cannot be called with an empty action type
- Redux Selector does not update when slice data is updated HOT 2
- GSSP ajax-mode -- HYDRATE-action not dispatching
- Types issue with 8.0.1 version of Next Redux Wrapper and Nextjs 13.4.19
- Strange Hydration action
- Typescript error when using object as parameter for makeStore function
- Wrapper doesn't support Next 14 HOT 4
- state getting empty before navigating to another SSR page.
- /!\ You are using legacy implementation. Please update your code: use createWrapper() and wrapper.useWrappedStore(). HOT 1
- wrapper.useWrappedStore(rest) not working when set NODE_ENV=test in nextjs-v14
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from next-redux-wrapper.