Redux toolkit store reset automatically in navigating between pages in next js - javascript

I'm a new Next user and have been using Redux with React for a long time
I had a lot of trouble in using Redux with Next
I'm done with this solution
store.js
import { configureStore } from '#reduxjs/toolkit';
import reducers from './rootReducer';
export function makeStore() {
return configureStore({
reducer: reducers,
});
}
const store = makeStore();
export default store;
rootReducer.js
import { combineReducers } from '#reduxjs/toolkit';
import tes from './test/tes';
const reducers = combineReducers({
test: tes,
});
export default reducers;
_app.js
import React from 'react';
import { Provider } from 'react-redux';
import store from '../redux/store';
import { createWrapper } from 'next-redux-wrapper';
const MyApp = ({ Component, ...rest }) => {
return (
<Provider store={store}>
<Component {...rest} />
</Provider>
);
};
const makestore = () => store;
const wrapper = createWrapper(makestore);
export default wrapper.withRedux(MyApp);
But I discovered that any use of the useDispatch
Inside any page, the search engine does not recognize the content of the page after fetching the data
import React, { useEffect } from 'react';
import { Test } from '../../redux/test/tes';
import { useDispatch, useSelector } from 'react-redux';
import Link from 'next/link';
function TestPage() {
const dispatch = useDispatch();
const { data } = useSelector((state) => state.test);
useEffect(() => {
dispatch(Test('hi'));
}, []);
return (
<div>
<Link href="/">
<a>home</a>
</Link>{' '}
{data.map((name) => (
<h1>{name.title}</h1>
))}
</div>
);
}
export default TestPage;
One of the next pre-render methods must be used
I wonder if this is normal with next
or there Is a better way for doing that?
#1 Update
Now after moving data fetching to getStaticProps
TestPage.js
import React from 'react';
import { Test } from '../../redux/test/tes';
import { useSelector } from 'react-redux';
import Link from 'next/link';
import { wrapper } from '../../redux/store';
function TestPage({ pageProps }) {
const { data } = useSelector((state) => state.test);
console.log(data);
return (
<div>
<Link href="/">
<a>home</a>
</Link>{' '}
{data && data.map((name) => (
<h1>{name.name}</h1>
))}
</div>
);
}
export const getStaticProps = wrapper.getStaticProps(
(store) => async (context) => {
const loading = store.getState().test.loading;
if (loading === 'idle') {
await store.dispatch(Test('hi'));
}
return {
props: { },
};
}
);
export default TestPage;
The problem now is that the store is not updating
useSelector return []
Although console.log (data) from getStaticProps the data is present
__NEXT_REDUX_WRAPPER_HYDRATE__
i'm stuck
#2 Update
It was really hard to get here and after that, there are still problems getting Redux with Next js
Now everything works until navigating to any page have getStaticProps or getServerProps
state getting reset automatically
store.js
import reducers from './rootReducer';
import { configureStore } from '#reduxjs/toolkit';
import { createWrapper, HYDRATE } from 'next-redux-wrapper';
const reducer = (state, action) => {
if (action.type === HYDRATE) {
let nextState = {
...state,
...action.payload,
};
return nextState;
} else {
return reducers(state, action);
}
};
const isDev = process.env.NODE_ENV === 'development';
const makeStore = (context) => {
let middleware = [];
const store = configureStore({
reducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(middleware),
devTools: isDev,
preloadedState: undefined,
});
return store;
};
export const wrapper = createWrapper(makeStore, { debug: isDev });

In the end, this way only worked. Even the server and Client state separation did not work.
I used this jsondiffpatch.
rootReducer.js
const rootReducer = createReducer(
combinedReducers(undefined, { type: '' }),
(builder) => {
builder
.addCase(HYDRATE, (state, action) => {
const stateDiff = diff(state, action.payload);
const isdiff = stateDiff?.test?.data?.[0];
const isdiff1 =
stateDiff?.test1?.data?.[0]
return {
...state,
...action.payload,
test: isdiff ? action.payload.test : state.test,
test1: isdiff1 ? action.payload.test1 : state.test1,
};
})
.addDefaultCase(combinedReducers);
}
);
The only problem here is that you have to test every change in every piece inside the state
Update
Because a global hydrate reducer can be overkill, here is an example to handle hydration in each slice:
import { createSlice, createAsyncThunk } from '#reduxjs/toolkit';
import { diff } from 'jsondiffpatch';
import { HYDRATE } from 'next-redux-wrapper';
const initialState = {
data: [],
};
export const TestFetch = createAsyncThunk(
'TestFetch',
async (data, { rejectWithValue, dispatch }) => {
try {
const response = await fetch(
'https://jsonplaceholder.typicode.com/users'
);
const d = await response.json();
return d;
} catch (error) {
return rejectWithValue(error.response.data.error);
}
}
);
const test = createSlice({
name: 'test',
initialState,
reducers: {
update: {
reducer: (state, { payload }) => {
return { ...state, data: payload };
},
},
},
extraReducers: {
[HYDRATE]: (state, action) => {
const stateDiff = diff(state, action.payload);
const isdiff1 = stateDiff?.server?.[0]?.test?.data?.[0];
// return {
// ...state,
// data: isdiff1 ? action.payload.server.test.data : state.data,
// };
state.data = isdiff1 ? action.payload.server.test.data : state.data;
},
[TestFetch.fulfilled]: (state, action) => {
state.data = action.payload;
},
},
});
export const { update } = test.actions;
export default test.reducer;

1.) Does using Redux with Nextjs eliminate the SEO advantage?
No, using Redux with NextJs does not hinder the SEO advantage. Redux goes well with NextJS.
The problem lies with your implementation of the data fetching. NextJS does not see the fetched content, because you need to fetch it in either getInitialProps, getServerSideProps, or getStaticProps depending on the way you want your app to work.
See the Data Fetching documentation from NextJS.
Note that getServerSideProps and getStaticProps are the recommended ways of dealing with data fetching.
If you go for getStaticProps, you will need getStaticPaths. Check this answer to see use cases and the difference between the getStaticPaths and getStaticProps as it can be confusing.
TLDR; Instead of putting the data fetching in a useEffect hook, move it inside a getServerSideProps or a getStaticProps function.

Related

basereducer is not a function - Redux Toolkit with createasyncthunk

I am using redux-toolkit to acquire accessToken from MSAL and redux-persist to persist the store in localStorage. I'm getting search results in clientlisting page. When I refresh the page it was working fine. But few minutes ago it throws me an error "Error in function eval in ./node_modules/redux-persist/es/persistReducer.js:144 baseReducer is not a function" I couldn't figure where am I doing wrong
store.js
import { configureStore } from '#reduxjs/toolkit'
import usersReducer from "./userSlice";
import storage from 'redux-persist/lib/storage';
import { persistReducer, persistStore } from 'redux-persist';
const persistConfig = { key: 'root', storage, }
const persistedReducer = persistReducer(persistConfig, usersReducer)
export const store = configureStore(
{
reducer: {
users: persistedReducer,
}
})
export const persistor = persistStore(store)
userSlice.js
import { useMsal } from "#azure/msal-react";
import { createAsyncThunk, createSlice } from "#reduxjs/toolkit";
import { loginRequest } from "./authConfig";
import { msalInstance } from "./pages/index";
export const fetchUsersToken = createAsyncThunk(
"users/fetchUsersToken",
async (dispatch, getState) => {
try {
const token = await msalInstance.acquireTokenSilent(dispatch)
.then((data) => data.accessToken)
return token
} catch (error) {
return error.response.data
}
}
);
const usersSlice = createSlice({
name: "users",
initialState: {
users: null,
loading: true
},
reducers: {},
extraReducers(builder) {
builder
.addCase(fetchUsersToken.pending, (state, action) => {
state.loading = true
})
.addCase(fetchUsersToken.fulfilled, (state, action) => {
state.loading = false,
state.users = action.payload
})
.addCase(fetchUsersToken.rejected, (state, action) => {
state.loading = false
});
}
})
export default usersSlice.reducer;
index.js
import React from "react"
import { Provider, useDispatch } from "react-redux";
import {persistor, store} from "../../store";
import Footer from "../Footer"
import { createTheme, ThemeProvider } from "#mui/material/styles"
import { PersistGate } from 'redux-persist/integration/react';
// Global styles and component-specific styles.
//For changing default blue color for mui text-fields
const theme = createTheme({
palette: {
primary: { main: "#000000" },
},
})
const Layout = ({ children }) => (
<div>
<ThemeProvider theme={theme}>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
{children}
<Footer/>
</PersistGate>
</Provider>
</ThemeProvider>
</div>
)
export default Layout
LandingPage.js ( where I'm dispatching the action.)
const request = {
...loginRequest,
account: accounts[0]
}
store.dispatch(fetchUsersToken(request))
Here is my index.js ( where msalInstance initiated )
import React from "react"
import { Helmet } from "react-helmet"
import { PublicClientApplication } from "#azure/msal-browser"
import { MsalProvider, useMsal } from "#azure/msal-react"
import { loginRequest, msalConfig } from "../authConfig"
import PageLayout from "../components/PageLayout"
import App from "./app"
import Layout from "../components/Layout"
//Redux
import { Provider, useDispatch } from "react-redux";
import {store} from "../store";
//Redux Ends here
export const msalInstance = new PublicClientApplication(msalConfig)
export default function Home() {
return (
<>
<Helmet>
<title>Client Engagement Lookup</title>
</Helmet>
<MsalProvider instance={msalInstance}>
{/* <Provider store={store}> */}
<Layout>
<PageLayout />
</Layout>
{/* </Provider> */}
</MsalProvider>
</>
)
}
After copy/pasting the code you shared into a running codesandbox I wasn't able to reproduce the error you describe, but I do see some discrepancies in the code, specifically in the userSlice.js file.
The main discrepancy I see is that the thunk is incorrectly accessing the thunkAPI. createAsyncThunk payload creators do take two arguments, the first is the arg (e.g. the request object) that is passed to the function and the second is the thunkAPI object. Update the thunk to correctly destructure dispatch and getState from the thunkAPI object.
export const fetchUsersToken = createAsyncThunk(
"users/fetchUsersToken",
async (request, { dispatch, getState }) => { // <-- destructure thunkAPI
try {
const { accessToken } = await msalInstance.acquireTokenSilent(request);
return accessToken;
} catch (error) {
return error.response.data;
}
}
);
A second discrepancy I noticed was in the fetchUsersToken.fulfilled reducer case where a Comma operator was used between the lines to set the loading and users states. This doesn't really effect much though since each operand mutates the state independently, but should still be fixed for readability's and maintenance's sake.
const usersSlice = createSlice({
name: "users",
initialState: {
users: null,
loading: true
},
extraReducers(builder) {
builder
.addCase(fetchUsersToken.pending, (state, action) => {
state.loading = true;
})
.addCase(fetchUsersToken.fulfilled, (state, action) => {
state.loading = false; // <-- own line, expression
state.users = action.payload; // <-- own line, expression
})
.addCase(fetchUsersToken.rejected, (state, action) => {
state.loading = false;
});
}
});
export default usersSlice.reducer;

How to dispatch an action from inside getInitialProps?

I am trying to implement Redux in a Next.js app and have problems getting the dispatch function to work in getInitialProps. The store is returned as undefined for some reason that I cannot figure out. I am using next-redux-wrapper. I have followed the documentation on next-redux-wrapper GitHub page but somewhere on the way it goes wrong. I know the code is working - I used axios to directly fetch the artPieces and then it worked just fine but I want to use Redux instead. I am changing an react/express.js app to a Next.js app where I will use the API for the basic server operations needed. This is just a small blog app.
Here is my store.js:
import { createStore } from 'redux';
import { createWrapper, HYDRATE } from 'next-redux-wrapper';
// create your reducer
const reducer = (state = { tick: 'init' }, action) => {
switch (action.type) {
case HYDRATE:
return { ...state, ...action.payload };
case 'TICK':
return { ...state, tick: action.payload };
default:
return state;
}
};
// create a makeStore function
const makeStore = (context) => createStore(reducer);
// export an assembled wrapper
export const wrapper = createWrapper(makeStore, { debug: true });
And here is the _app.js:
import './styles/globals.css';
import { wrapper } from '../store';
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default wrapper.withRedux(MyApp);
And finally here is where it does not work. Trying to call dispatch on the context to a sub component to _app.js:
import React from 'react';
import { ArtPiecesContainer } from './../components/ArtPiecesContainer';
import { useDispatch } from 'react-redux';
import axios from 'axios';
import { getArtPieces } from '../reducers';
const Art = ({ data, error }) => {
return (
<>
<ArtPiecesContainer artPieces={data} />
</>
);
};
export default Art;
Art.getInitialProps = async ({ ctx }) => {
await ctx.dispatch(getArtPieces());
console.log('DATA FROM GETARTPIECES', data);
return { data: ctx.getState() };
};
This should probably work with "next-redux-wrapper": "^7.0.5"
_app.js
import { wrapper } from '../store'
import React from 'react';
import App from 'next/app';
class MyApp extends App {
static getInitialProps = wrapper.getInitialAppProps(store => async ({Component, ctx}) => {
return {
pageProps: {
// Call page-level getInitialProps
// DON'T FORGET TO PROVIDE STORE TO PAGE
...(Component.getInitialProps ? await Component.getInitialProps({...ctx, store}) : {}),
// Some custom thing for all pages
pathname: ctx.pathname,
},
};
});
render() {
const {Component, pageProps} = this.props;
return (
<Component {...pageProps} />
);
}
}
export default wrapper.withRedux(MyApp);
and Index.js
import { useEffect } from 'react'
import { useDispatch } from 'react-redux'
import { END } from 'redux-saga'
import { wrapper } from '../store'
import { loadData, startClock, tickClock } from '../actions'
import Page from '../components/page'
const Index = () => {
const dispatch = useDispatch()
useEffect(() => {
dispatch(startClock())
}, [dispatch])
return <Page title="Index Page" linkTo="/other" NavigateTo="Other Page" />
}
Index.getInitialProps = wrapper.getInitialPageProps(store => async (props) => {
store.dispatch(tickClock(false))
if (!store.getState().placeholderData) {
store.dispatch(loadData())
store.dispatch(END)
}
await store.sagaTask.toPromise()
});
export default Index
For the rest of the code you can refer to nextjs/examples/with-redux-saga, but now that I'm posting this answer they're using the older version on next-redux-wrapper ( version 6 ).

Function is not getting called anymore, when trying to dispatch a type

I am currently trying to access my data using the Spotify API. This works very well. Thats the function I am using to get my Data. I assume the other stuff is not important. I can post that, if you need that.
export const getSpotifyUser = (access_token:string) =>{
setAuthorizationHeader(access_token)
axios.get('https://api.spotify.com/v1/me').then((res) => {
console.log(res.data)
})
}
I have set up a redux store and trying to put the credentials into the store, by dispatching the right type (SET_USER).
export const getSpotifyUser = (access_token:string) => (dispatch: any) => {
console.log("function is not called") // Function is not even called why ?
setAuthorizationHeader(access_token)
axios.get('https://api.spotify.com/v1/me').then((res) => {
console.log(res.data)
dispatch ({
type: SET_USER,
payload: res.data
})
}
but as soon as I use dispatch, the function is no longer called.
I really do not see my mistake. Is that a typescript error ?. ( I am using react typescript)
store.js
import { createStore, applyMiddleware } from 'redux'
import rootReducer from './rootReducer'
import { composeWithDevTools } from 'redux-devtools-extension'
import thunk from 'redux-thunk'
const store = createStore(
rootReducer,
composeWithDevTools(applyMiddleware(thunk))
)
// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch
export default store
rootReducer.ts
import { combineReducers } from 'redux'
import userReducer from './User/userReducer'
const rootReducer = combineReducers({
user: userReducer,
})
export default rootReducer
userReducer.ts
import { AnyAction } from 'redux'
import { SET_USER } from './userTypes'
interface Credentials {
username: string
email: string
profilepicture: string
id: number
}
interface InitialState {
authenticated: boolean
loadding: boolean
credentials?: Credentials
}
const initialState: InitialState = {
authenticated: false,
loadding: false,
credentials: {} as Credentials,
}
const reducer = (state = initialState, action: AnyAction) => {
switch (action.type) {
case SET_USER: {
return {
...state,
loading: false,
credentials: action.payload,
}
}
default:
return state
}
}
export default reducer
Login.tsx ( I am making the login here. It is working fine, if am not using dispatch
import { IonButton } from '#ionic/react'
import React, { useEffect } from 'react'
import {
getAuthorizeHref,
getHashParams,
removeHashParamsFromUrl,
getSpotifyUser,
} from '../../Helpers/login'
const Login: React.FC = () => {
// const user = useSelector((state: RootState) => state.user.credentials)
useEffect(() => {
const hashParams = getHashParams()
const access_token = hashParams.access_token
// const expires_in = hashParams.expires_in
removeHashParamsFromUrl()
getSpotifyUser(access_token)
}, [])
return (
<IonButton onClick={() => window.open(getAuthorizeHref(), '_self')}>
)}
export default Login
since you're using typescript with react, I believe you have added the getSpotifyUser function to your interface, now if you want to access that i think you should call it like this
props.getSpotifyUser(access_token)
and finally add it to your connect as a dispatch function that's wrapping your component
your login component should be like this one
import { IonButton } from '#ionic/react'
import React, { useEffect } from 'react'
import { connect } from 'react-redux'
import {
getAuthorizeHref,
getHashParams,
removeHashParamsFromUrl,
getSpotifyUser,
} from '../../Helpers/login'
interface ILogin {
getAuthorizeHref: () => any;
getHashParams: () => any;
removeHashParamsFromUrl: () => any;
getSpotifyUser: (access_token) => any;
}
const Login: React.FC = (props: ILogin) => {
// const user = useSelector((state: RootState) => state.user.credentials)
useEffect(() => {
const hashParams = props.getHashParams()
const access_token = hashParams.access_token
// const expires_in = hashParams.expires_in
props.removeHashParamsFromUrl()
props.getSpotifyUser(access_token)
}, [])
return (
<IonButton onClick={() => window.open(props.getAuthorizeHref(), '_self')}>
)}
export default connect(null, {getAuthorizeHref, getHashParams, removeHashParamsFromUrl, getSpotifyUser})(Login)
Basicly Shamim has given the right answer.Any function that uses that dispatch is a redux action, and you have to follow the docs specifically to call that function. You have to use connect to dispatch actions. As an alternative you can use the dispatchHook. If am wrong please please correct me !!!!
Thats the right code I just had to correct Login.tsx
import { IonApp, IonButton } from '#ionic/react'
import React, { useEffect } from 'react'
import { connect } from 'react-redux'
import {
getAuthorizeHref,
getHashParams,
removeHashParamsFromUrl,
getSpotifyUser,
} from '../../Helpers/login'
const style = {
Logo: {
display: 'flex',
justifyContent: 'space-evenly',
color: 'white',
position: 'relative',
top: '70%',
} as const,
}
const Login: React.FC = (props: any) => {
// const user = useSelector((state: RootState) => state.user.credentials)
useEffect(() => {
const hashParams = getHashParams()
const access_token = hashParams.access_token
// const expires_in = hashParams.expires_in
removeHashParamsFromUrl()
console.log('halloeuseeffect')
props.getSpotifyUser(access_token)
console.log('halloeuseeffect')
}, [])
return (
<IonApp>
<IonButton onClick={() => window.open(getAuthorizeHref(), '_self')}>
knsnan
</IonApp>
)
}
export default connect(null, {
getSpotifyUser,
})(Login)

How to dispatch in .then() in react-redux

I am working on project where I am stuck in this problem. The thing is, I am calling an axios API and after its success I want to update my redux state i.e. in the .then() chain of axios. How can I achieve that? As what I have tried by applying what I know is -> I have created a react-redux dispatch in my component. I know how to do this in normal onClick but in then method I don't know how to trigger that.
I have tried doing this:
let submitForm = (e) => {
e.preventDefault();
// Axios request
const url = 'http://localhost:5000/api/v1/users/login'
axios({
//Api details
})
.then(res => {
// Store API data in LocalStorage
})
.then(() => {
LogIN(); // Here I want to change redux state //
history.push('/dashboard')
})
}
--Component
function Signin({LogIN}) {
return (
)
}
const mapDispatchToProps = dispatch => {
return {
LogIN: () => dispatch(login_action())
}
}
export default connect(null , mapDispatchToProps)(Signin)
After doing this, I see same state with no difference
Here is redux:
const login_action = () => {
return {
type : 'LOG-IN'
}
}
const loginLogOutReducer = (state = false, action) => {
switch (action.type) {
case 'LOG_IN':
return !state
default:
return state
}
}
const AllReducers = combineReducers({
isLoggedIn : loginLogOutReducer
})
You can use redux-thunk and function component in react hook
App.js
import {Provider} from 'react-redux'
import store from './store'
<Provider store={store()}>
<AppComponent />
</Provider>
store.js
import {applyMiddleware, compose, createStore} from 'redux'
import thunk from 'redux-thunk'
import {initialState, rootReducer} from './reducers'
const store = () => {
return createStore(rootReducer, initialState, compose(applyMiddleware(thunk)))
}
export default store
reducer.js
import {actionTypes} from './actionTypes'
const initialState = {}
const rootReducer = (state = initialState, action) => {
if (action.type === actionTypes.STH) {
return {
...state,
sth: action.payload,
}
}
}
export {initialState, rootReducer}
actionTypes.js
export const actionTypes = {
STH: 'STH'
}
Component
...
const onChange = => {
dispatch(actionFunc()).then(res => {
// DO Something
})
...
action.js
const actionFunc = () => {
return (dispatch, getState) => {
return axios({
//Api details
}).then(res => res).catch(err => err)
}
}

Redux-thunk dispatch function doesn't work on Laravel

I'm using React-Laravel for my project.
The problem is when I tried to use redux-thunk for the asynchronous dispatch function.
My dispatch function won't get executed.
Please do help me figure out this problem.
I have already tried to use promise or redux-devtools-extension library
https://codeburst.io/reactjs-app-with-laravel-restful-api-endpoint-part-2-aef12fe6db02
app.js
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import logger from 'redux-logger';
import Layout from './jsx/Layout/Layout';
import marketplaceReducer from './store/reducers/marketplace';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const appReducer = combineReducers({
marketplace: marketplaceReducer
});
const rootReducer = (state, action) => {
return appReducer(state, action);
}
const store = createStore(rootReducer, composeEnhancers(
applyMiddleware(logger, thunk)
));
const render = (
<Provider store={store}>
<BrowserRouter>
<Layout />
</BrowserRouter>
</Provider>
);
ReactDOM.render(render, document.getElementById('root'));
marketplace.js (action)
import * as actionTypes from './actionTypes';
import axios from '../../axios';
export const loadMarketplace = () => {
console.log("Load Marketplace");
return {
type: actionTypes.LOAD_MARKETPLACE
};
}
export const successMarketplace = (data) => {
console.log("Success Marketplace");
return {
type: actionTypes.SUCCESS_MARKETPLACE,
data: data
}
}
export const failedMarketplace = () => {
console.log("Failed Marketplace");
return {
type: actionTypes.FAILED_MARKETPLACE
}
}
export const showMarketplace = () => {
console.log("Show Marketplace Action")
return dispatch => {
//This is the problem
//Inside this function, I can't see any console.log, even loadMarketplace() didn't get called.
console.log("Show Marketplace in dispatch");
dispatch(loadMarketplace());
axios.get('/marketplaces')
.then(response => {
dispatch(successMarketplace(response));
})
.catch(error => {
dispatch(failedMarketplace());
});
};
}
marketplace.js (reducer)
import * as actionTypes from '../actions/actionTypes';
const initial_state = {
data: [],
loading: false
}
const loadMarketplace = (state, action) => {
console.log("Load Marketplace Reducer")
return {
...state,
loading: true
};
}
const successMarketplace = (state, action) => {
console.log("Success Marketplace Reducer", action.data)
return {
...state,
loading: false,
data: action.data
};
}
const failedMarketplace = (state, action) => {
return {
...state,
loading: false
};
}
const reducer = (state = initial_state, action) => {
//This is called when the first init, never got it through showMarketplace() function.
console.log("Marketplace Reducer", action);
switch (action.type) {
case actionTypes.LOAD_MARKETPLACE: return loadMarketplace(state, action);
case actionTypes.SUCCESS_MARKETPLACE: return successMarketplace(state, action);
case actionTypes.FAILED_MARKETPLACE: return failedMarketplace(state, action);
default: return state;
}
}
export default reducer;
Marketplace.js (jsx view)
import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../../../store/actions';
class Marketplace extends Component {
componentDidMount() {
console.log('[ComponentDidMount] Marketplace')
this.props.showMarketplace();
}
render() {
return (
<React.Fragment>
Marketplace
</React.Fragment>
);
}
}
const mapDispatchToProps = dispatch => {
return {
showMarketplace: () => dispatch(actions.showMarketplace)
};
}
export default connect(null, mapDispatchToProps)(Marketplace);
This is the result of my console.log (when loading the first time for Marketplace.js)
Please do help, I've been struggling for 2 hours or more, only because of this problem. (This is my first time using React-Laravel).
Thank you.
I already found the problem. It is not redux-thunk problem.
It is actually a normal Redux problem we found anywhere.
Marketplace.js (jsx view)
import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../../../store/actions';
class Marketplace extends Component {
componentDidMount() {
console.log('[ComponentDidMount] Marketplace')
this.props.showMarketplace();
}
render() {
return (
<React.Fragment>
Marketplace
</React.Fragment>
);
}
}
const mapDispatchToProps = dispatch => {
return {
showMarketplace: () => dispatch(actions.showMarketplace) //THIS IS THE PROBLEM, IT IS NOT EXECUTING PROPERLY. THIS ONE SHOULD BE
showMarketplace: () => dispatch(actions.showMarketplace()) //SHOULD BE LIKE THIS.
};
}
export default connect(null, mapDispatchToProps)(Marketplace);
Edited: I think it is something about thunk is not added right to redux.
First of all try to add only thunk.
const store = createStore(rootReducer, composeEnhancers(
applyMiddleware(thunk)
));
If it works, maybe try to change the order of them.

Categories