我是Redux的新手,我想知道是否有人对处理非React事件(如窗口调整大小)的最佳做法有一些建议。在我的研究中,我从React官方文档中找到了此链接:https : //facebook.github.io/react/tips/dom-event- listeners.html
我的问题是,在使用Redux时,应该将窗口大小存储在我的商店中还是应该将其保持在单独的组件状态?
好问题。我想在我的商店中使用用户界面。减速器的外观可能如下所示:
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是一个常量字符串。)
SCREEN_RESIZE
function screenResize(width) { return { type: SCREEN_RESIZE, screenWidth: width }; }
最后,将其与事件侦听器连接在一起。我将以下代码放在初始化store变量的地方。
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状态的任何其他内容都会丢失。
ui
largeScreen