Должен ли я хранить ссылки на функции в магазине Redux?
Я пытаюсь создать поддержку ярлыков клавиатуры в моем приложении React/Redux в идиоматическом режиме React/Redux. Способ, которым я планирую это сделать, - создать следующий создатель действия и связанное с ним действие:
registerShortcut(keyCode, actionCreatorFuncReference)
Затем редуктор обновит зарегистрированный объектShortcuts в магазине redux с отображением keyCodes в actionCreatorFuncReferences. Затем мой корневой компонент будет прослушивать клавиатуру и посмотреть, есть ли зарегистрированный ключевой код, и если да, то отправьте отображаемое действие с помощью ссылки на функцию создания действия.
Однако это будет первый раз, когда я храню ссылки на функции в моем хранилище Redux. На сегодняшний день у меня были только объекты с ключами с значениями ванили (строки, int и т.д.).
В документах Redux говорится: "Вы должны делать все возможное, чтобы сохранить сериализуемое состояние. Не помещайте в него ничего, что вы не можете легко превратить в JSON". Означает ли это, что это плохая идея хранить такие ссылки на функции в моем хранилище Redux? Если это так, то лучший способ выполнить то, что я пытаюсь сделать в React/Redux?
Альтернативный подход заключается только в том, чтобы хранить сопоставление ключевых кодов и ссылок на функции в самом корневом компоненте реакции, но это не очень напоминало Redux, поскольку теперь состояние приложения не находится в хранилище Redux.
Ответы
Ответ 1
Нет, вы не должны хранить ссылки на функции в магазине redux. Они не являются сериализуемыми, и, как вы упомянули, состояние должно быть сериализуемым в любое время. Самый приемлемый для меня подход, который я могу придумать, - это просто сохранить карту горячих клавиш в их actionCreatorFuncNames.
Ответ 2
Я новичок в redux, но, как я его вижу, вы можете передать key code и тип действия.
Затем редуктор может прослушивать этот тип действия и вносить соответствующие изменения.
Вот пример использования библиотеки Mousetrap:
// On your Container
function registerShortcut(element, dispatch, keyCode, actionType) {
Mousetrap(element).bind(keyCode, function(e) {
dispatch({
type: actionType,
payload: {
keyCode: keyCode,
event: e
}
});
});
});
mapDispatchToProps = function(dispatch) {
return {
onMount: function(element) {
registerShortcut(element, dispatch, ['command+f', 'ctrl+f'], 'OPEN_SEARCH');
},
onUnmount: function(element) {
Mousetrap(element).unbind(['command+f', 'ctrl+f']);
}
};
};
// On your Component
componentDidMount() {
onMount(ReactDOM.findDOMNode(this));
};
componentWillUnmount() {
onUnmount(ReactDOM.findDOMNode(this));
};
// On your reducer
function reducer(oldState, action) {
if (action.type == 'OPEN_SEARCH') {
//... make changes ...//
return newState;
}
return oldState;
};
Таким образом, сочетания клавиш отправят действие. Редуктор внесет необходимые изменения в состояние. И, наконец, приложение может повторно выполнить рендеринг.