Hello I am working on Shopping List and my file looks like this:
import React, { Component } from 'react';
import AppNavbar from './components/AppNavbar';
import ShoppingList from './components/ShoppingList';
import {Provider} from 'react-redux';
import store from './';
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';
function App() {
return (
<Provider store={store}>
<div className="App">
<AppNavbar/>
<ShoppingList/>
</div>
</Provider>
);
}
export default App;
However, Ireceived this error:
Failed to compile
./src/App.js
Attempted import error: './' does not contain a default export (imported as 'store').
can someone please help fix this ?
The problem in your code is how you are trying load the store with import store from './';.
Instead you need to use createStore() from redux as the following:
import { createStore, applyMiddleware } from 'redux';
const store = createStore(
/* your reducers */,
applyMiddleware( /* your middleware */ ),
);
What you can pass to the <Provider /> as follows:
ReactDOM.render(<Provider store={store}>
<App />
</Provider>, document.getElementById('root'));
Read further here about createStore(reducer, \[preloadedState\], \[enhancer\]) which:
Creates a Redux store that holds the complete state tree of your app. There should only be a single store in your app.
I hope this helps!
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import reducers from './reducers';
import Posts from './containers/Posts'
import NavBar from './components/NavBar';
// Apply Thunk middleware
const middleware = applyMiddleware(thunk);
// Create store
const store = createStore(reducers, enhancer);
class App extends Component {
render() {
return (
<Provider store={store}>
<React.Fragment>
<NavBar />
<Posts />
</React.Fragment>
</Provider>
);
As you can see, the app.js page should be looked like this. You can't just import store from another file. It's better to use best practices like this.
Now you will wonder how the reducers came from. Generally, developers put all the reducers in a reducers folder. In that folder you can have a index.js file and other reducer files. For now, you better use a empty main reducer index.js like below.
import { combineReducers } from 'redux'
const rootReducer = combineReducers({
null
})
export default rootReducer;
If you something like post or whatever, the code should be modified like this.
import { combineReducers } from 'redux'
import posts from './posts';
const rootReducer = combineReducers({
posts: posts
})
export default rootReducer;
Simply, posts is a post reducer in the reducers folder. Selecting a appropriate middleware is up to you. I have used redux-thunk. You can use redux-saga, redux-logic, or custom middleware. I think this will help you to solve your problem.
Related
createStore is #deprecated so im trying to replace with configurationStore, i think the post data from my cluster is not showing because of that
```
import React from 'react';
import ReactDom from 'react-dom/client';
import { Provider } from 'react-redux';
import {createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import reducers from "./reducers";
import App from './App'
const store = createStore(reducers, (compose(applyMiddleware(thunk))))
const root = ReactDom.createRoot(document.getElementById("root"));
root.render(
<Provider store={store}>
<App />
</Provider>
);
And im trying to do it like this:
import React from 'react';
import ReactDom from 'react-dom/client';
import { Provider } from 'react-redux';
import { applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import { configureStore } from '#reduxjs/toolkit'
import reducers from "./reducers";
import App from './App'
const store = configureStore(reducers, (compose(applyMiddleware(thunk))))
const root = ReactDom.createRoot(document.getElementById("root"));
root.render(
<Provider store={store}>
<App />
</Provider>
);
```
Of Course it didn't work i'm trying to figure out how it could be
You would do
const store = configureStore({ reducer: reducers })
The thunk middleware is active automatically. compose and applyMiddleware are not needed any more. So is combineReducers.
If you had
const reducers = combineReducers({
a: reducerA,
b: reducerB
})
you could also just instead do
const store = configureStore({
reducer: {
a: reducerA,
b: reducerB
}
})
If you were still using createStore, that means that you were generally using an outdated style of Redux that is about 4x times the code of modern Redux.
Modern Redux does not use switch..case reducer, ACTION_TYPE constants, immutable reducer logic, hand-written action creators or connect & mapStateToProps. You might have been misled by an outdated tutorial.
I would highly recommend you to follow the official Redux tutorial which will leave you with knowledge of modern Redux and in the end much cleaner and easy to maintain code.
As the title says, I'm mapping through an array I have from an api in UserCardList component and it works fine but once I wrap App with PersistGate, it gives me "TypeError: users.map is not a function" and the error message from redux logger is "redux-persist: persist timed out for persist key "root". I really don't know what I'm doing wrong.
Any help would be highly appreciated.
index.js
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import { store, persistor } from "./redux/store";
import "./index.css";
import "tachyons";
import App from "./containers/App";
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<PersistGate persistor={persistor}>
<App />
</PersistGate>
</BrowserRouter>
</Provider>,
document.getElementById("root")
redux store
import { createStore, applyMiddleware } from "redux";
import { persistStore } from "redux-persist";
import thunkMiddleware from "redux-thunk";
import { createLogger } from "redux-logger";
import rootReducer from "../redux/root-reducer";
const logger = createLogger();
const middlewares = [logger, thunkMiddleware];
export const store = createStore(rootReducer, applyMiddleware(...middlewares));
export const persistor = persistStore(store);
export default { store, persistor };
root-reducer
import { combineReducers } from "redux";
import { persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
import requestUsers from "./reducers";
const persistConfig = {
key: "root",
storage,
whitelist: ["users"],
};
const rootReducer = combineReducers({
users: requestUsers,
});
export default persistReducer(persistConfig, rootReducer);
UserCardList component
import React, { Fragment } from "react";
import UserCard from "./UserCard";
const UserCardList = ({ users }) => {
return (
<Fragment>
<h1 className="f1"> Users </h1>
{users.map((user) => {
return (
<UserCard
key={user.login.uuid}
image={user.picture.large}
firstName={user.name.first}
lastName={user.name.last}
email={user.email}
city={user.location.city}
country={user.location.country}
/>
);
})}
</Fragment>
);
};
export default UserCardList;
I have created a sample project here by taking the code from your question and everything looks fine for me. And the store is getting created and users is coming as expected.
There could be a possible error in the reducers which is not posted here. Please have a look at the sample project, hope it helps.
I see in redux store you have this:
export const store = createStore(rootReducer, applyMiddleware(...middlewares));
export const persistor = persistStore(store);
// you dont need line below, you exported store and persistore in lines above
export default { store, persistor };
In my case, adding timeout: null to the persist configuration solved my issue.
const persistConfig = {
key: 'keyOfStore',
storage: storage,
// There is an issue in the source code of redux-persist (default setTimeout does not cleaning)
timeout: null,
}
const appReducer = combineReducers({
...otherReducers,
keyOfStore: persistReducer(persistConfig, keyOfStoreRedfucer),
})
Got the solution from here
I am trying to build a Trello clone using React and Redux.
Details of the application:
The application consists of 4 columns called TODO, DOING, DONE and REJECTED
I can add card to any of the 4 columns.
In the card I have just plain text.
The cards can be further moved into any of the columns using a package called react-beautiful-dnd.
There is also a delete button sticked to each card to delete the card which is added.
What I am trying to do?
I have a sample data which is first rendered when the application is first loaded.
The data is just demo, and contains id, text property for each and every card.
I want to use localstorage to add the card and further delete the card.
I want to use possibly Redux subscribe to achieve this.
I do not have much experience in dealing with Redux and localstorage altogether.
How can I do this?
Any help would be really appreciated and much required.
I have my codesandbox where I have my application running. Please consider checking out to help me out.
https://codesandbox.io/s/small-violet-zmbtf
You have to use redux persist
// configureStore.js
import { createStore } from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web
import rootReducer from './reducers'
const persistConfig = {
key: 'root',
storage,
}
const persistedReducer = persistReducer(persistConfig, rootReducer)
export default () => {
let store = createStore(persistedReducer)
let persistor = persistStore(store)
return { store, persistor }
}
// App.js
import { PersistGate } from 'redux-persist/integration/react'
// ... normal setup, create store and persistor, import components etc.
const App = () => {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<RootComponent />
</PersistGate>
</Provider>
);
};
Edited check below:
change codesandbox to:
store/index.js:
// store/index.js:
import { createStore } from "redux";
import { persistStore } from "redux-persist";
import rootReducer from "../reducers";
export const store = createStore(rootReducer);
export const persistor = persistStore(store);
*******
reducers/index.js:
// reducers/index.js:
import { combineReducers } from "redux";
import { persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
import listReducers from "./listReducers";
const persistConfig = {
key: "root",
storage,
whitelist: ["lists"]
};
export default persistReducer(persistConfig, combineReducers({
lists: listReducers
}));
root project index.js:
// index.js:
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import { store, persistor } from "./store";
import "./styles/main.scss";
import App from "./components/App";
import * as serviceWorker from "./serviceWorker";
ReactDOM.render(
<Provider store={store}>
<PersistGate persistor={persistor}>
<App />
</PersistGate>
</Provider>,
document.getElementById("root")
);
serviceWorker.unregister();
I wonder how rootReducer is used in the official redux todo list example on https://redux.js.org/basics/example-todo-list. It looks like reducers are not getting called after the rootReducer is passed to the store.
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import rootReducer from './reducers'
import App from './components/App'
const store = createStore(rootReducer)
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
Here is my code:
store.js
import {createStore, applyMiddleware, compose} from 'redux';
import {fromJS} from 'immutable';
import {routerMiddleware} from 'react-router-redux';
import createSagaMiddleware from 'redux-saga';
import createReducer from './reducers';
const sagaMiddleware = createSagaMiddleware();
export default function configureStore(initialState = {}, history) {
// Create the store with two middlewares
// 1. sagaMiddleware: Makes redux-sagas work
// 2. routerMiddleware: Syncs the location/URL path to the state
const middlewares = [sagaMiddleware, routerMiddleware(history)];
const enhancers = [applyMiddleware(...middlewares)];
const store = createStore(createReducer, fromJS(initialState), enhancers);
// Extensions
store.runSaga = sagaMiddleware.run;
store.asyncReducers = {}; // Async reducer registry
return store;
}
Routes.js
import React from 'react';
import {Route, Router, IndexRoute, browserHistory} from 'react-router';
import {syncHistoryWithStore} from 'react-router-redux';
import store from './store';
import Welcome from './containers/Welcome';
const history = syncHistoryWithStore(browserHistory, store);
const routes = (
<Router history={history}>
<Route path="/">
<IndexRoute component={Welcome} />
</Route>
</Router>
);
export default routes;
Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {browserHistory} from 'react-router';
import { Providers } from 'react-redux';
import configureStore from './store';
import routes from './routes';
const initialState = {};
const store = configureStore(initialState, browserHistory);
ReactDOM.render(
<Provider store={store}>
{routes}
</Provider>, document.getElementById('main-content')
);
I can't find where the culprit is. I tried to debug it, but can't found what really make it those error. error: Uncaught TypeError: store.getState is not a function
Any solution?
This is a typo that generated the error: TypeError: store.getState is not a function
Wrong
const store = createStore(()=>[], {}, applyMiddleware);
Correct
const store = createStore(()=>[], {}, applyMiddleware());
Notice the added parenthesis () on applyMiddleware.
in my case i got this error because my store was as shown below which is a function:
const store = preloadedState => {
let initialState={}
//some code to modify intialState
return createStore(reducer, initialState)
}
but in index.js i was passing store as a function and not the value it was returning.
wrong
<Provider store={store}>
<MyApp />
</Provider>
correct
<Provider store={store()}>
<MyApp />
</Provider>
Notice that in your Routes.js the store is not being initialized properly. You should add these lines:
const initialState = {};
const store = configureStore(initialState, browserHistory);
as in your index.js file.
I was doing this (a dynamic require) ..
const store = require('../store/app')
state = store.getState()
but for some reason when using require instead of import you have to do this ..
const store = require('../store/app')
state = store.default.getState()
Not sure if this will help but you named your import { Providers } instead of { Provider } from react-redux library.
In index.js we have to provide store() method as props value instead of store.
<Provider store={store()}>
{routes}
</Provider>
Updated index.js file.
import React from 'react';
import ReactDOM from 'react-dom';
import {browserHistory} from 'react-router';
import { Providers } from 'react-redux';
import configureStore from './store';
import routes from './routes';
const initialState = {};
const store = configureStore(initialState, browserHistory);
ReactDOM.render(
<Provider store={store()}>
{routes}
</Provider>, document.getElementById('main-content')
);
this is the solution, good luck 🤞
import { applyMiddleware, combineReducers, createStore } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import thunk from 'redux-thunk'
const reducer = combineReducers({
products: []
})
const middleware = [thunk]
const store = createStore(
reducer,
composeWithDevTools(applyMiddleware(...middleware))
)
export default store
TypeError: store.getState is not a function -This error often occurs when you are not properly initializing middleware function. What you need to do is as below
You need to add paranthesis on applyMiddleware ( ) function and then it will behave as you are expecting it to do.
const store = createStore(()=>[], {}, applyMiddleware());
Replacing store with store() worked for me. Written below:
<Provider store={store()}>
{routes}
</Provider>