我正在构建一个可以执行 SSR(服务器端渲染)的单个应用程序,并且我正在使用 React + Redux。
我刚刚开始在此应用程序中实现 Redux。它之前是仅使用 React 的
useState
、useContext
等构建的应用程序。
事实是,有时我需要我的应用程序代码了解其运行的环境,例如 ON_CLIENT
或
ON_SERVER
,以跳过某些
window.something
语句。在
Redux 之前,我做了以下事情:
index.js(这可能是我的客户端包或服务器包的index.js)
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>
);
然后,在某个组件内,我可以执行此模式:
SomeComponent.js
const {ON_CLIENT} = useContext(EnvironmentContext);
ON_CLIENT && window.something;
我想用
Redux 改进这种模式。
我想将其保留在 Redux 商店中,这样我就可以摆脱EnvironmentContext
并通过以下方式访问它:
const {ON_CLIENT} = useSelector((state) => state.environment);
所以我想到了这样做:
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
}
});
但是由于我没有针对这个状态的相应减速器(
environment
),所以我得到了这个错误消息:
注意:redux.js:319 在传递给 createStore 的 preloadedState 参数中发现意外的键“environment”。 期望找到已知的减速器键之一:“auth”、“appVersion”、“siteData”。意外的按键将被忽略。
auth
、
appVersion
和
siteData
是我有相应减速器的状态。这是我的
rootReducer
:
const rootReducer = combineReducers({
auth: updateAuth,
appVersion: updateClientVersion,
siteData: updateSiteData
});
问题
我可以有一些不会改变的状态,因此不被任何减速器处理吗?或者在这种情况下,我确实需要设置一些虚拟减速器只是为了始终返回相同的状态? PS:它确实有效,但感觉不对。
// 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
});
有人有更好的替代方案吗?
我看过这个讨论:
https://github.com/reduxjs/redux/issues/1457
有一些建议来填充全局对象,但我宁愿将其全部保留在React
和
Redux
中。
PS: 抱歉问了这么长的问题,但我想让我的用例尽可能清晰,这样有人可能有更好的模式。