when i tried user store in my test
import React from 'react';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import { mount } from 'enzyme';
import chai from 'chai';
import App from '../layouts/App';
import store from '../redux/configureStore';
const expect = chai.expect;
// let store;
let app;
describe('login', () => {
beforeEach(() => {
app = mount (
<Provider store={store}>
<App />
</Provider>
)
})
but i got No reducer provided for key "dashboard"
here is my configStore main code
const reducer = {
dashboard,
PageLogin,
};
const store = createStore(
reducer,
composeEnhancers(applyMiddleware(sagaMiddleware))
);
I got PageLogin, but can't got dashboard
and there is dashboard main code
export {
snackbarActions,
dialogActions,
userConfigActions,
authActions,
progressActions,
UserProfileActions,
// ...
};
You need to use combineReducers to combine your reducers
import { combineReducers } from 'redux'
const reducer = combineReducers({
dashboard,
PageLogin,
})
Related
I am getting error while facing redux-toolkit with nexjs.
The warning message is like
You are using legacy implementation. Please update your code: use
createWrapper() and wrapper.useWrappedStore()
I tried a few solutions which i found online, but still getting the same warning. Here is my code below
_app.tsx
import Head from "next/head";
import { useEffect } from "react";
import { reduxWrapper } from "../store/wrapper";
import { Provider } from "react-redux";
import "../styles/tailwind.css";
import "../styles/globals.css";
function MyApp({ Component, pageProps }) {
const { store } = reduxWrapper.useWrappedStore(pageProps);
return (
<Provider store={store}>
<Component {...pageProps} />
</Provider>
);
}
export default reduxWrapper.withRedux(MyApp);
reduxWrapper file
import {configureStore} from '#reduxjs/toolkit'
import createSagaMiddleware from 'redux-saga'
import {createWrapper} from 'next-redux-wrapper'
import rootReducer from './reducer'
import initialState from './state'
import rootSaga from './saga'
declare module 'redux' {
export interface Store {
sagaTask: any
}
}
const USE_DEV_TOOLS = process.env.NODE_ENV !== 'production'
export const makeStore = (context) => {
const sagaMiddleware = createSagaMiddleware()
const store = configureStore({
reducer: rootReducer,
preloadedState: initialState,
middleware: [sagaMiddleware],
devTools: USE_DEV_TOOLS
})
store.sagaTask = sagaMiddleware.run(rootSaga)
return store
}
export const reduxWrapper = createWrapper(makeStore)
I receive an error when following a YouTube crash course on redux:
redux.js:158 Uncaught Error: Expected the root reducer to be a function. Instead, received: ''
at createStore (redux.js:158:1) | at redux.js:682:1 | at createStore (redux.js:154:1) | at ./src/state/store.js (store.js:5:1)
I suspect the error is inside store.js, but I'm not able to debug it. And, why '' is returned? Very much grateful for your help.
store.js
import { legacy_createStore as createStore, applyMiddleware } from "redux";
import reducers from "./reducers/index"
import thunk from "redux-thunk"
export const store = createStore(
reducers,
{},
applyMiddleware(thunk)
)
reducers/index.js
import { combineReducers } from "redux";
import accountReducer from "./accountReducer";
const reducers = combineReducers ({
account : accountReducer
});
export default reducers;
reducers/accountReducer.js
const reducer = (state = 0, action) => {
switch (action.type) {
case "deposit":
return state + action.payload;
case "withdraw":
return state - action.payload;
default:
return state
}
};
export default reducer;
App.js
import {useSelector, useDispatch} from "react-redux"
import {bindActionCreators} from "redux"
import {actionCreators} from "./state/index"
function App() {
const account = useSelector((state) => state.acoount );
const dispatch = useDispatch()
const {depositMoney, withdrawMoney} = bindActionCreators(actionCreators, dispatch)
return (
<div className="App">
<h1>{account}</h1>
<button onClick={() => depositMoney(1000)}>Deposit</button>
<button onClick={() => withdrawMoney(1000)}>Withdraw</button>
</div>
);
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App' ;
import reportWebVitals from './reportWebVitals';
import { Provider } from 'react-redux';
import {store} from './state/store'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Provider store = {store}>
<App />
</Provider>
</React.StrictMode>
);
reportWebVitals();
I am getting the error "Error: Cannot read properties of undefined (reading 'getState')"
Not sure what is the issue but I have followed all instructions. I do not resolve it at all after searching everything. My app is in next.js and I want to add redux into it. Here is my code
/* pages/_app.js */
import App from "next/app"
import { Provider } from "react-redux"
import React from "react"
import { createWrapper } from "next-redux-wrapper"
import store from "../store/store"
class MyApp extends App {
static async getInitialProps({ Component, ctx }) {
const pageProps = Component.getInitialProps
? await Component.getInitialProps(ctx)
: {}
//Anything returned here can be accessed by the client
return { pageProps: pageProps }
}
render() {
//pageProps that were returned from 'getInitialProps' are stored in the props i.e. pageprops
const { Component, pageProps, store } = this.props
return (
<Provider store={store}>
<Component {...pageProps} />
</Provider>
)
}
}
//makeStore function that returns a new store for every request
const makeStore = () => store
const wrapper = createWrapper(makeStore)
export default wrapper.withRedux(MyApp)
//store/store.js
import { createStore, applyMiddleware } from "redux"
import thunk from "redux-thunk"
import rootReducer from "../reducers/rootReducer"
import { composeWithDevTools } from "redux-devtools-extension"
const initialState = { counter: 0 }
const middleware = [thunk]
const store = createStore(
rootReducer,
initialState,
composeWithDevTools(
applyMiddleware(...middleware)
// other store enhancers if any
)
)
export default store
///reducers/rootReducer.js
import counterReducer from "./counterReducer"
import { combineReducers } from "redux"
const rootReducer = combineReducers({
counter: counterReducer,
})
export default rootReducer
//counterReducer.js //
const counterReducer = (state = { value: 0 }, action) => {
return { ...state }
}
export default counterReducer
I'm trying to use mobx-rest with mobx-rest-axios-adapter and mobx-react, and I have trouble making the component rerender upon async data retrieval.
Here's my data model, in state/user.js:
import { Model } from 'mobx-rest';
class User extends Model {
url() {
return '/me';
}
}
export default new User();
This is the React component, in App.js:
import React from 'react';
import { inject, observer } from 'mobx-react';
import { apiClient } from 'mobx-rest';
import createAdapter from 'mobx-rest-axios-adapter';
import axios from 'axios';
import { compose, lifecycle, withProps } from 'recompose';
const accessToken = '...';
const API_URL = '...';
const App = ({ user }) => (
<div>
<strong>email:</strong>
{user.has('email') && user.get('email')}
</div>
);
const withInitialise = lifecycle({
async componentDidMount() {
const { user } = this.props;
const axiosAdapter = createAdapter(axios);
apiClient(axiosAdapter, {
apiPath: API_URL,
commonOptions: {
headers: {
Authorization: `Bearer ${accessToken}`,
},
},
});
await user.fetch();
console.log('email', user.get('email'));
},
});
export default compose(
inject('user'),
observer,
withInitialise,
)(App);
It uses recompose to get the user asynchronously from an API in componentDidMount(), and once available the component is supposed to show the user email. componentDidMount() prints the email once available.
Finally this is index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import createBrowserHistory from 'history/createBrowserHistory';
import { Provider } from 'mobx-react';
import { RouterStore, syncHistoryWithStore } from 'mobx-react-router';
import { Router } from 'react-router';
import App from './App';
import { user } from './state/user';
const documentElement = document.getElementById('ReactApp');
if (!documentElement) {
throw Error('React document element not found');
}
const browserHistory = createBrowserHistory();
const routingStore = new RouterStore();
const stores = { user };
const history = syncHistoryWithStore(browserHistory, routingStore);
ReactDOM.render(
<Provider {...stores}>
<Router history={history}>
<App />
</Router>
</Provider>,
documentElement,
);
My problem is that the component doesn't rerender once the user is retrieved and the email is available, although the console log shows that it is returned ok in the async request. I've tried playing around with mobx-react's computed, but no luck. Any ideas?
I think it will work if you change your compose order of App.js:
export default compose(
inject('user'),
withInitialise,
observer,
)(App);
According to the MobX official document,
Tip: when observer needs to be combined with other decorators or
higher-order-components, make sure that observer is the innermost
(first applied) decorator; otherwise it might do nothing at all.
How should I use redux with apollo 2.x.x beside graphql ?
I have this error
"configureStore.js:11 Uncaught TypeError: Cannot read property 'reducer' of undefined
at ./src/store/configureStore.js.exports.default"
and it seems to be related to the cache instanse of apollo
import React from "react";
import ReactDOM from "react-dom";
import AppRouter from "./routers/AppRouter";
import registerServiceWorker from "./registerServiceWorker";
// 1
import { ApolloProvider } from "react-apollo";
import { ApolloClient } from "apollo-client";
import { HttpLink } from "apollo-link-http";
import { InMemoryCache } from "apollo-cache-inmemory";
import { ApolloLink } from 'apollo-client-preset';
import {AUTH_TOKEN} from './lib/constants';
import configureStore from './store/configureStore';
import "./styles/App.css";
const httpLink = new HttpLink({ uri: "http://localhost:3000/graphql" });
const middlewareAuthLink = new ApolloLink((operation, forward) => {
const token = localStorage.getItem(AUTH_TOKEN);
const authorizationHeader = token ? `Bearer ${token}` : null
operation.setContext({
headers: {
authorization: authorizationHeader
}
})
return forward(operation)
})
const httpLinkWithAuthToken = middlewareAuthLink.concat(httpLink)
console.log("httpLink",httpLink);
console.log("httpLinkWithAuthToken",httpLinkWithAuthToken);
const store =configureStore();
export const client = new ApolloClient({
link: httpLinkWithAuthToken,
cache: new InMemoryCache()
});
const jsx = (
<ApolloProvider store={store} client={client}>
<AppRouter />
</ApolloProvider>
);
ReactDOM.render(jsx, document.getElementById("app"));
registerServiceWorker();
and the store in configured in this way :
import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
import {client} from "../app";
import thunk from "redux-thunk";
import { ApolloClient } from "apollo-client";
export default ()=>{
const store =createStore(
combineReducers({
// classes:classes ,
apollo:client.reducer(),
}),
{}, //initial state
compose(
applyMiddleware(client.middleware()),
thunk.withExtraArgument(client),
// If you are using the devToolsExtension, you can add it here also
(typeof window.__REDUX_DEVTOOLS_EXTENSION__ !== 'undefined') ? window.__REDUX_DEVTOOLS_EXTENSION__() : f => f,
)
);
return srore;
}