import { configureStore } from "#reduxjs/toolkit";
import testSlice from "./testSlice";
import {combineReducers} from "redux";
const rootReducer = combineReducers({test: testSlice})
export const store = configureStore({
reducer: rootReducer,
});
Which one is better? for performance and use purpose. Which is good to use?
They are totally different things.
The reducer option is an object of slice reducers, like {users : usersReducer, posts : postsReducer}, configureStore will automatically create the root reducer by passing this object to the Redux combineReducers utility. See here
RTK configureStore setup the redux store configuration, not only reducer, but also middlewares, dev tools, preloaded state, and enhancers.
The Redux combineReducers helper function turns an object whose values are different reducing functions into a single reducing function
Related
So this piece of code works without problems in my react js app.
import reducers from "./reducer";
import middlewareFunctions from "./middleware";
import { createStore, combineReducers, applyMiddleware } from "redux";
const middleware = (store) => (next) => (action) => {
const fn = Object.keys(middlewareFunctions).find(
(key) => key === action.type
);
if (fn) return middlewareFunctions[fn](store, next, action);
return next(action);
};
export default createStore(
combineReducers(reducers),
{},
applyMiddleware(middleware)
);
However when I convert to react typescript it shows me that createStore is deprecated.
And its recommended to use the configureStore method of the #reduxjs/toolkit package, which replaces createStore.
I read the details on Redux docs page: https://redux.js.org/introduction/why-rtk-is-redux-today
But I am still struggling to understand how to adapt my code for configureStore
1. Question: Why is createStore deprecated on my React Typescript app but not on React Javascript?
2. Question: What is the correct approach now? Simply switching createStore to configureStore does not work.
createStore is also deprecated in javascript: https://github.com/reduxjs/redux/pull/4336/
Question: Why is createStore deprecated on my React Typescript app but not on React Javascript?
It's also deprecated in javascript https://github.com/reduxjs/redux/pull/4336/
It's easier to use configureStore with typescript (from all of my experience with redux) because with configureStore you can easily create your state types, dispatch types etc...
Now the recommanded way to use do a redux application is with configureStore.
FYI:
configureStore use createStore internally
Question: What is the correct approach now? Simply switching createStore to configureStore does not work.
The correct approach now is to use configureStore from redux-toolkit.
I was experimenting with redux for a bit and came across a problem, I found the solution( here: React Redux - Error passing several store enhancers to createStore()) however this is not the solution I wanted. Basically I have the same problem as the person asking the question basically when creating the redux store we did this:
import { createStore, applyMiddleware } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import reduxThunk from 'redux-thunk';
import rootReducer from "./reducers";
const store = createStore(
rootReducer,
composeWithDevTools(applyMiddleware(reduxThunk)),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
But the code above is not the correct way of creating the store, apparently you should create the store is like this:
import { createStore, compose, applyMiddleware } from "redux";
import reduxThunk from "redux-thunk";
import rootReducer from "./reducers";
const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
rootReducer,
composeEnhancer(applyMiddleware(reduxThunk))
);
However in the solution above I am not using the composeWithDevTools module which is what I wanted to use. Is there a way to use composeWithDevTools in this case and is it necessary to use composeWithDevTools?
Today you should be using our official Redux Toolkit package to write your Redux logic, and in particular, RTK's configureStore API.
configureStore automatically sets up the Redux DevTools Extension for you, automatically turns on the thunk middleware, and also makes it very easy to add additional store enhancers if desired.
The example you're showing would simply be:
const store = configureStore({
reducer: rootReducer
});
and the behavior is exactly the same as what you showed.
I'm trying to integrate simpreWebRTC to my React-Redux project, but the library has their own redux store and the documentation says this:
"The provided createStore function makes a basic Redux
store useful for getting things started. If you want to
make your own, import reducer from '#andyet/simplewebrtc' and
be sure to assign it to simplewebrtc in the top level of
your state object."
I've tried several approaches but nothing works, any idea? what I'm missing here?
Thanks
This is the code that I have so far:
store.js
import {createStore, applyMiddleware} from 'redux'
import rootReducer from './reducers/index'
import thunk from 'redux-thunk';
export default createStore(rootReducer, applyMiddleware(thunk));
const store = createStore(rootReducer);
console.log(store.getState());
./reducers/index.js
import {combineReducers} from 'redux'
import {reducer as simplewertc} from '#andyet/simplewebrtc'
import liveRoomReducer from './liveRoomReducer'
export default combineReducers({simplewertc, liveRoomReducer});
./reducers/liveRoomReducer.js
const initialState = {
test : 'test'
};
export default function liveRoomReducer(state=initialState, action) {
return state;
};
I'm logging the store state in the console and is showing simplewebrtc on it:
And still showing this error:
Creating your own store with thunk middleware and using combineReducers should do the trick:
import {combineReducers} from 'redux';
import {reducer as simplewebrtc} from '#andyet/simplewebrtc';
import reducer1 from 'path/to/your/reducer1';
import reducer2 from 'path/to/your/reducer2';
export default combineReducers({simplewebrtc, reducer1 , reducer2});
If that isn't working for you please provide what error is showing up if any and some example code of how you create your redux store and root reducer.
Edit: After seeing the updated question with code, we found the problem was in a typo when importing the reducer.
I am using flux. I have used combineReducers - all works. But what is the purpose of using combineReducers in the redux?
any one help me to understand by updating my code?
why should I combine Reducers ?
if I am not use, what is the impact ?
here is my code :
import { combineReducers } from "redux";
import rootReducer from "./countAddReducer";
export default combineReducers({
value: rootReducer
});
Live Demo with sample app
combineReducers is used to combine all the reducers to one single store object, so that it can be used in every component.
In flux, you would have different Flux Stores to manage different state. With Redux, there is just one store, but combineReducers helps you keep the same logical division between reducers.
In your example,
export default combineReducers({
value: rootReducer,
removes: countRemoveReducer
});
you got two reducers rootReducer and countRemoveReducer, and you combine these two make available in the components connect() method as mapStateToProps, where mapStateToProps have a state object which contains both these reducers.
Now, if you want to share state between two reducers then we cannot achieve it with combineReducers. For that purpose we need redux-thunk.
I have updated your code, https://codesandbox.io/s/lq87v947
It separates the state corresponding to a particular reducer into their own object.
Example:
import { combineReducers } from "redux";
import userReducer from "./userReducer";
import blogPost from "./blogReducer";
export default combineReducers({
user: userReducer,
blogPost: blogReducer,
});
When you start dispatching actions to either userReducer or blogReducer, the global redux state is just one object, but that object looks like this.
const reduxState = {
user: {
//state created by userReducer will go in here
},
blogPost: {
//state created by blogReducer will go in here
}
}
I've been through many examples to understand how Redux-Thunk works and most the time the store is configured in a various way. I guess there's the old way or the new way but I'm kind of lost. Here is three pattern that I've identified. If someone can explain me the differences between them :
The simple way :
import { createStore, applyMiddleware } from 'redux';
import thunkMiddleware from 'redux-thunk'
import createLogger from 'redux-logger'
const loggerMiddleware = createLogger()
const store = createStore(rootReducer, applyMiddleware( thunkMiddleware, loggerMiddleware));
the Official Reddit Async Exemple way (here) :
import { createStore, applyMiddleware } from 'redux'
import thunkMiddleware from 'redux-thunk'
import createLogger from 'redux-logger'
const loggerMiddleware = createLogger()
export default function configureStore(preloadedState) {
return createStore(
rootReducer,
preloadedState,
applyMiddleware(
thunkMiddleware,
loggerMiddleware
)
)
}
the old way ?
import {compose, createStore, applyMiddleware } from 'redux';
import thunkMiddleware from 'redux-thunk';
const createAppStore = compose(
applyMiddleware(thunkMiddleware)
)(createStore);
export default function configureStore(initialState){
const store = createAppStore(rootReducer, initialState);
return store;
};
From there I have at least four questions :
Do we still need to use compose ? I only find it in "old" exemple ?
Is there any differences between import ReduxThunk from
'redux-thunk' and import thunkMiddleware from 'redux-thunk' ?
Does the simple way is also correct ?
I don't understand the preloadedState pattern from the Reddit Async Exemple.
thanks.
The signature for createStore is createStore(reducer, [preloadedState], [enhancer]).
preloadedState is an initial state you load before you initialize your app. For instance, if you prerender your first page on a server and want to pass app state as a JSON inside your HTML. Sometimes you need to fetch this state asynchronously that is where the second example is useful. You fetch your state and create a store using that state in the callback of your ajax call.
The third argument.
enhancer is a higher-order function that composes a store creator to return a new, enhanced store creator. applyMiddleware is a store enhancer shipped with redux. If you want to combine multiple store enhancers you need to use compose function.
For instance, redux-devtools-extension for chrome is an enhancer so to use it in your app you would need compose function
let store = createStore(reducer, initialState, compose(
applyMiddleware(...middleware),
window.devToolsExtension ? window.devToolsExtension() : f => f
));
When you import something from 'redux-thunk' you use default export so you can name your variable as you want. It doesn't matter.
A simple way is also correct if you don't need anything fancy it would work just fine.