调整窗口大小 - React + Redux [英] Window Resize - React + Redux

查看:17
本文介绍了调整窗口大小 - React + Redux的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Redux 的新手,我想知道是否有人有一些关于处理非 React 事件(如窗口大小调整)的最佳实践的提示.在我的研究中,我从 React 官方文档中找到了这个链接:https://facebook.github.io/react/tips/dom-event-listeners.html

I'm new to Redux and I'm wondering if anyone has some tips on best practices for handling non React events like window resize. In my research, I found this link from the official React documentation: https://facebook.github.io/react/tips/dom-event-listeners.html

我的问题是,在使用 Redux 时,我应该将窗口大小存储在我的 Store 中还是应该将其保持在我的单个组件状态?

My questions is, when using Redux, should I store the window size in my Store or should I be keeping it in my individual component state?

推荐答案

好问题.我喜欢在我的商店中有一个 ui 部分.其减速器可能如下所示:

Good question. I like to to have a ui part to my store. The reducer for which might look like this:

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 是一个常量字符串.)

The action for which is pretty boilerplate. (SCREEN_RESIZE being a constant string.)

function screenResize(width) {
    return {
        type: SCREEN_RESIZE,
        screenWidth: width
    };
}

最后,您将其与事件侦听器连接在一起.我会将以下代码放在您初始化 store 变量的位置.

Finally you wire it together with an event listener. I would put the following code in the place where you initialise your store variable.

window.addEventListener('resize', () => {
    store.dispatch(screenResize(window.innerWidth));
});

媒体查询

如果您的应用采用更二进制的屏幕尺寸视图(例如大/小),您可能更喜欢使用媒体查询.例如

Media Queries

If your app takes a more binary view of screen size (e.g. large/small), you might prefer to use a media query instead. e.g.

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());
    }
});

(这次我将省略 action 和 reducer 代码.它们的样子很明显.)

(I'll leave out the action and reducer code this time. It's fairly obvious what they look like.)

这种方法的一个缺点是可能会使用错误的值初始化商店,并且我们依赖媒体查询在商店初始化后设置正确的值.除了将媒体查询推入减速器文件本身之外,我不知道解决此问题的最佳方法.欢迎反馈.

One drawback of this approach is that the store may be initialised with the wrong value, and we're relying on the media query to set the correct value after the store has been initialised. Short of shoving the media query into the reducer file itself, I don't know the best way around this. Feedback welcome.

现在我考虑了一下,您可能可以通过执行以下操作来解决此问题.(但请注意,我尚未对此进行测试.)

Now that I think about it, you can probably get around this by doing something like the following. (But beware, I have not tested this.)

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());
    }
});

更新 II: 最后一种方法的缺点是 ui 对象将替换整个 ui 状态,而不仅仅是 largeScreen 字段.任何其他的初始 ui 状态都会丢失.

UPDATE II: The drawback of this last approach is that the ui object will replace the entire ui state not just the largeScreen field. Whatever else there is of the initial ui state gets lost.

这篇关于调整窗口大小 - React + Redux的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆