好问题。我想在我的商店中使用用户界面。减速器的外观可能如下所示:
const initialState = { screenWidth: typeof window === 'object' ? window.innerWidth : null};function uiReducer(state = initialState, action) { switch (action.type) { case SCREEN_RESIZE: return Object.assign({}, state, { screenWidth: action.screenWidth }); } return state;}动作很漂亮。(
SCREEN_RESIZE是一个常量字符串。)
function screenResize(width) { return { type: SCREEN_RESIZE, screenWidth: width };}最后,将其与事件侦听器连接在一起。我将以下代码放在初始化
store变量的地方。
window.addEventListener('resize', () => { store.dispatch(screenResize(window.innerWidth));});媒体查询
如果您的应用使用屏幕大小的更二进制视图(例如,大/小),则您可能更喜欢使用媒体查询。例如
const mediaQuery = window.matchMedia('(min-width: 650px)');if (mediaQuery.matches) { store.dispatch(setLargeScreen());} else { store.dispatch(setSmallScreen());}mediaQuery.addListener((mq) => { if (mq.matches) { store.dispatch(setLargeScreen()); } else { store.dispatch(setSmallScreen()); }});(这次我将省略动作和Reducer代码。很明显它们看起来是什么样子。)
这种方法的一个缺点是商店可能用错误的值初始化,并且我们依靠媒体查询在商店初始化后设置正确的值。缺少将媒体查询推入reducer文件本身的过程,我不知道解决此问题的最佳方法。欢迎反馈。
更新
现在我考虑了一下,您可以通过执行以下操作来解决此问题。(但是请注意,我尚未对此进行测试。)
const mediaQuery = window.matchMedia('(min-width: 650px)');const store = createStore(reducer, { ui: { largeScreen: mediaQuery.matches }});mediaQuery.addListener((mq) => { if (mq.matches) { store.dispatch(setLargeScreen()); } else { store.dispatch(setSmallScreen()); }});更新二: 最后一种方法的缺点是
ui对象将替换整个
ui状态,而不仅仅是
largeScreen字段。初始
ui状态的任何其他内容都会丢失。



