Reputation: 31335
I'm building a Single App that will do SSR (server side rendering) and I'm using React + Redux.
I've just started to implement Redux in this app. It was previously built app using only React's useState
, useContext
etc.
The fact is that sometimes I need my app code to be aware of the environment that it's running, either ON_CLIENT
or ON_SERVER
, to skip some window.something
statement, for example.
Before Redux, I was doing the following:
index.js (this could be the index.js of my client bundle or my server bundle)
ReactDOM.render(
<App
ON_SERVER={false} // THIS IS TRUE ON SERVER CODE
ON_CLIENT={true} // THIS IS TRUE ON CLIENT CODE
... other stuff
/>
,document.getElementById('root')
);
App.js
...
const environment = {
ON_SERVER: props.ON_SERVER,
ON_CLIENT: props.ON_CLIENT
}
...
// PROVIDING IT USING REACT CONTEXT
return (
<EnvironmentContext.Provider value={environment}>
<MyComponents/>
</EnvironmentContext.Provider>
);
And then, inside some component, I can do this pattern:
SomeComponent.js
const {ON_CLIENT} = useContext(EnvironmentContext);
ON_CLIENT && window.something;
And I want to improve this pattern with Redux.
I want to keep this in the Redux store, so I can get rid of the EnvironmentContext
and access it with:
const {ON_CLIENT} = useSelector((state) => state.environment);
So I've thought of doing:
index.js
const store = createStore(rootReducer, {
environment: {
ON_CLIENT: true, // THIS IS TRUE ON CLIENT CODE
ON_SERVER: false // THIS IS TRUE ON SERVER CODE
}
});
But since I don't have a corresponding reducer for this piece of state (environment
), I got this error msg:
redux.js:319 Unexpected key "environment" found in preloadedState argument passed to createStore. Expected to find one of the known reducer keys instead: "auth", "appVersion", "siteData". Unexpected keys will be ignored.
NOTE: auth
, appVersion
and siteData
are pieces of state which I have corresponding reducers for.
Here is my rootReducer
:
const rootReducer = combineReducers({
auth: updateAuth,
appVersion: updateClientVersion,
siteData: updateSiteData
});
QUESTION
Can I have some piece of state that will not change, and therefore is not handled by any reducer? Or in this case I do need to set up some dummy reducer just to always return that same state? PS: It does the trick, but it feels wrong, though.
// NOTE: I will always preload this state, in the `createStore` call, so the state will never be undefined.
function returnEnvironment(state={}, action) {
return state;
}
const rootReducer = combineReducers({
auth: updateAuth,
appVersion: updateClientVersion,
siteData: updateSiteData,
environment: returnEnvironment
});
Does anybody have a better alternative to this?
I've looked at this discussion: https://github.com/reduxjs/redux/issues/1457
There are some suggestions to populate the global object, but I'd rather keep it all inside React
and Redux
.
PS: Sorry for the long question, but I wanted to make my use case as clear as I could, so somebody might have a better pattern.
Upvotes: 4
Views: 805
Reputation: 109
Redux is designed for data centralisation and management such as loading some dynamic data changing it during the application lifetime and so on.Since you are not going to change that values because your application can’t run in both environments on a same time or switch between them that mean you don’t need to change them during application lifetime and if some variable should not change value it should be declared as a CONSTANT. So declare it as a constant and important whenever you need to access it.
Upvotes: 1