Мне иногда полезно использовать редуктор window
, который отслеживает такие вещи, как размер экрана, высота прокрутки и другие атрибуты, на которые будут опираться некоторые из моих компонентов. Я бы создал создателя действия, который я установил в компоненте верхнего уровня, чтобы любое изменение размера или действие прокрутки могло обновлять хранилище redux, и таким образом мне не нужно было бы прикреплять эти обработчики к каждому компоненту, зависящему от свойств окна.
Обратите внимание, что это может привести к серьезным изменениям производительности, поэтому использование функции дебюта и/или дросселирования для уменьшения количества срабатываний, связанных с действием, имеет важное значение.
Таким образом, в любом компоненте оболочки для приложения или в самых верхних компонентах, вы могли бы сделать что-то вроде этого:
import { throttle, debounce } from 'lodash';
...
...
constructor(props){
super(props);
this.scrollHandler = this.scrollHandler.bind(this);
this.resizeHandler = this.resizeHandler.bind(this);
this.update = this.update.bind(this);
}
scrollHandler() {
throttle(this.update, 250)();
}
resizeHandler() {
debounce(this.update, 500)();
}
update() {
const { updateWindow } = this.props;
const {
innerHeight,
innerWidth,
outerHeight,
outerWidth,
pageYOffset,
scrollY
} = window;
updateWindow({
innerHeight,
innerWidth,
outerHeight,
outerWidth,
pageYOffset,
scrollY
});
}
componentDidMount() {
this.update();
window.addEventListener('scroll', this.scrollHandler, false);
window.addEventListener('resize', this.resizeHandler, false);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.scrollHandler, false);
window.removeEventListener('resize', this.resizeHandler, false);
}
И редуктор может выглядеть примерно так:
const DEFAULT_WINDOW = {
innerWidth: 0,
innerHeight: 0,
outerWidth: 0,
outerHeight: 0,
pageYOffset: 0,
scrollY: 0,
scrollingUp: false,
scrollingDown: false
};
const window = (
state = DEFAULT_WINDOW,
action
) => {
const { data } = action;
switch (action.type) {
case types.UPDATE_WINDOW:
return assign({}, state, data, {
scrollingUp: data.pageYOffset < state.pageYOffset,
scrollingDown: data.pageYOffset > state.pageYOffset
});
default: return state;
}
};
Это не звучит как 'isMobile' будет когда-нибудь изменится, так что это не то, что вам действительно нужно государственный менеджер по. –
Первый раз, когда я возглавляю «MERN», мне это нравится. :) – Aaron
@ Иордан, ну, например, некоторые планшеты будут видеть разные взгляды на основе Пейзажа и Портрет. Поэтому, если я передам состояние: все компоненты могут реагировать на изменение состояния. – Sequential