Shall we use multiple combine reducers? - reactjs

I have three reducers
Home
Listing
Detail
I have one combine reducer for above three. But I want to divide project structure into multiple reducers. Is it a good practice to have multiple combine reducer in the project?

Yes, you can have multiple combineReducers in your App, You can at the top level combine reducers Home , Listing and Detail and even split each individual reducers into multiple and combine them into one.
According to the Redux docs:
You may call combineReducers at any level of the reducer hierarchy.
It doesn't have to happen at the top. In fact you may use it again to
split the child reducers that get too complicated into independent
grandchildren, and so on.
Some more description about combineReducer:
As your app grows more complex, you'll want to split your reducing
function into separate functions, each managing independent parts of
the state.
The combineReducers helper function turns an object whose values are
different reducing functions into a single reducing function you can
pass to createStore.
The resulting reducer calls every child reducer, and gathers their
results into a single state object. The shape of the state object
matches the keys of the passed reducers.

Yes, you can combine multi reducer and use it as one store,
Firstly, you should import all reducers in a new file. then, combine all reducers with combine-reducer technics,like this:
import { combineReducers } from 'redux';
import {Home,Listing,Detail} from '*/**';
const rootReducer = combineReducers({
Home,
Listing,
Detail
})
export default rootReducer
Secondly, import the new file in Store file and create your store with combined-reducer
import { createStore } from 'redux'
import rootReducer from '*/combinestores'
const store = createStore(rootReducer)
console.log(store.getState())optinal
export default store
In the end, in your container you can use your store like this :
(but before it, you should be sure send store as props to Containers)
const mapStateToProps = state => {
return{
*name of your var* : state.Home.*,
*name of your var* : state.Detail.* /*then you can use this var as props anywhere you need*/
}
}
const mapDispatchToProps = dispatch => {
return{
*name of your var* : () => dispatch ( *name of your func*()),
*name of your var* : () => dispatch ( *name of your func*())
}
}
export default connect(mapStateToProps,mapDispatchToProps)(name of func);

Related

Importing redux action makes other actions undefined

This is one of the strangest things I have ever seen. It makes absolutely no sense to me. The short version is I have a Redux action creator function. If I import this function into this one particular component file, it makes every function imported from its file undefined.
So, let's start with the file filterInputModal.actions.js. This contains my Redux action functions, created using redux-starter-kit:
export const showAddCategoryModal = createAction('showAddCategoryModal');
That is the function I've been working with. Now, this function has long since been imported into my ManageVideoFilters.js component:
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { showAddCategoryModal } from 'store/filterInputModal/filterInputModal.actions';
const ManageVideoFilters = (props) => {
/* Component logic */
};
/* PropTypes and mapStateToProps */
const mapDispatchToProps = (dispatch) => bindActionCreators({
showAddCategoryModal: () => showAddCategoryModal() // Done this way to avoid passing in a payload, since certain default event payloads cause Redux to print console errors
});
export default connect(mapStateToProps, mapDispatchToProps)(ManageVideoFilters);
So far so good. Before we go and break everything, let's take a look at my filterInputModal.reducer.js Redux reducer, also created using Redux Starter Kit:
import { createReducer } from 'redux-starter-kit';
import { showAddCategoryModal } from './filterInputModal.actions';
const initialState = {}; // The initial state for the reducer goes here
const handleShowAddCategoryModal = (state) => {
/* handle updating the state */
return state;
};
const actionMap = {
[showAddCategoryModal]: handleShowAddCategoryModal
};
export default createReducer(initialState, actionMap);
The action map uses the action creator functions toString() as the key, and then I provide my own functions to handle updating the state. Again, at this point, everything is perfect. We will come back to the reducer in a sec, first let's break things.
Now we're going to my VideFileEdit.js component. If we add the following line to this component, everything breaks:
import { showAddCategoryModal } from 'store/filterInputModal/filterInputModal.actions';
So, how does it break?
The import of the showAddCategoryModal function in filterInputModal.reducer.js now is undefined.
Because the reducer is using the functions as the keys to handle actions, the reducer is no longer able to handle the action properly and update the state.
It gets weirder though. Here are some of the weird behaviors I'm seeing.
If I import this action into any other component, everything is fine. The import in the reducer is unchanged.
The import of the function in both ManageVideoFilters.js and VideoFileEdit.js is fine.
So, what can I try next? This is really strange and doesn't make any sense to me. I've never seen this before.
As the commenter said, the problem was recursive imports. My filterInputModal.reducer.js exported some constants, which were imported into my filterInputModal.actions.js. The actions from filterInputModal.actions.js were then imported into filterInputModal.reducer.js. Hence the recursive import.
I moved the constants into a new file, filterInputModal.constants.js, and viola, problem solved.

Using multiple redux connect HOCs in a single component

Hi 👋recently I saw an interesting piece of code.
There was this HOC:
import { connect } from 'react-redux'
const mapProps = store => ({
someProp: store.some.prop,
})
const withSomeProp = connect(mapProps)
export default withSomeProp
and then it was used like this:
export default compose(
withSomeProp,
connect(
mapProps,
mapDispatch
),
)
Is this approach good? Or should I be worried about potential performance issues or any other bugs?
I would generally recommend defining a more complex mapState function that extracts both pieces of data that this component needs, rather than defining multiple connect definitions just to extract different pieces of data.

`combineReducers` - not able to understand of requirement and usage

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
}
}

Update helper file with Redux store

I have a Colors.js file which contains some vars such as:
const textColor = 'white';
const primaryColor = 'blue';
I then import this file in a components styling and use it as such:
import Colors from './Colors';
const styles = {
component: { color: Colors.textColor }
}
Now I would like to connect this Colors.js file to my redux store; so I can theme my app. For example, wrapping my Colors.js file in a connect function, however, this doesn't work as the Colors.js is called way before the store is initialized.
I also tried getState() and importing the store manually, but I did not receive any props.
Is there a different approach I could take?
Thank you.
Make the colors.js into a reducer and set it as such. In the reducer, set your initialState to default colors you need, and also export that initialState object, so you can import it in other files. Now you can import that initialState and use it anywhere you want in the app, which will be constant, and also you will have that same colors object in redux store, which you can connect to any component you have and use and manipulate it too, with redux actions.

Options for dynamically adding reducers within a package being consumed

I have 2 node packages A and B with A consuming B. I have the store being defined using createStore and combineReducers in A. This just has the reducers in A.
I want to add a new reducer in package B. What are my options to connect it to the store? I've been looking at redux-injector. The other thing I am thinking of is to move reducer from package B to A but that would mean that B would have to consume A and will create a cycle.
Are there any better ways of handling this?
According to your requirement
A-->
store.jsx
B-->
reducer1.js
reducer2.js
So in store.jsx you will import reducers from package B
as
import reducer1 from "../B/reducer1";
import reducer2 from "../B/reducer2";
const rootReducer = combineReducers({
reducer1,
reducer12,
});
export const configureStore = (initialState) => {
//your other store configuration
};
If you want to add any more reducer in package B simply import and add it to store.jsx file.
Where store.jsx is your store configuration.

Resources