我应该在Redux商店中存储函数引用吗?

Sac*_*khi 40 redux

我正在尝试以惯用的React/Redux方式为我的React/Redux应用程序构建键盘快捷方式支持.我计划这样做的方法是拥有以下动作创建者和相关动作:

registerShortcut(keyCode, actionCreatorFuncReference)
Run Code Online (Sandbox Code Playgroud)

然后,reducer将使用keyCodes到actionCreatorFuncReferences的映射更新redux存储中的registeredShortcuts对象.然后我的根组件将侦听keyup并查看是否注册了关联的keyCode,如果是,则通过action creator函数引用调度映射的action.

但是,这将是我第一次在Redux商店中存储函数引用.到目前为止,我只有带有香草值的键的对象(字符串,整数等).

Redux文档说:"你应该尽力保持状态可序列化.不要在其中加入任何你不能轻易变成JSON的东西." 这是否表明在我的Redux商店中存储此类函数引用是一个坏主意?如果是这样,有什么更好的方法来完成我在React/Redux中尝试做的事情?

另一种方法是在根反应组件本身中存储keyCodes和函数引用的映射,但是由于现在应用程序状态不在Redux存储中,因此感觉不像Redux.

Nat*_*gen 31

不,您不应该在redux商店中存储函数引用.它们不是可序列化的,正如您所提到的,状态应该是可序列化的.我能想到的最友好的redux方法就是将热键地图保存到actionCreatorFuncNames中.

  • 将功能存储在商店中是很好的 - 只要您了解所涉及的权衡.从常见问题解答:"如果您对持久性和时间旅行调试可能无法正常工作等问题感到满意,那么欢迎您将非可序列化的项目放入Redux商店." http://redux.js.org/docs/faq/OrganizingState.html#can-i-put-functions-promises-or-other-non-serializable-items-in-my-store-state (10认同)
  • 谁说 redux store 应该是可序列化的?除非您进行服务器渲染,否则我认为避免它没有价值。 (2认同)
  • 看起来 Redux 在这个问题上改变了主意:https://redux.js.org/style-guide/style-guide#do-not-put-non-serialized-values-in-state-or-actions Non-不建议使用可序列化的项目,除非它们旨在被中间件拦截。 (2认同)

Dav*_*dio 10

TL; DR:你没有.商店状态必须始终可序列化(如Nathan回答).Redux方式是通过增强器,或通过依赖项的Redux-Observable方式.

基于Redux文档示例,您想要的是在您的操作中传递引用(1),忽略它的reducer(2)并在增强器(3)中使用它:

//... in your action:
const data={val:1},ref=()=>{};
const action = {type:'ACTION_WITH_REF', data:data:, ref: ref}; //(1)

//... in your reducer:
case 'ACTION_WITH_REF':
return {...state, data: action.data}

//... and in your enhancer:
import { createStore, applyMiddleware } from 'redux'
import reducers from './reducers'
export const myRefStore= {};
?
function refHandler({ getState }) {
  return next => action => {
    switch(action.type){ // this can be done more elegantly with redux-observable
     case 'ACTION_WITH_REF':
     myRefStore.aRef = action.ref // (3)
     break;
 }
    const returnValue = next(action)   
    return returnValue
  }
}?
const store = createStore(
  reducers,
  initialState,
  applyMiddleware(refHandler)
)
Run Code Online (Sandbox Code Playgroud)

注意:只要你的增强剂没有副作用,你就可以了.请注意,您可以直接在reducer中获取refs,但是这种方法会将参考值保持在reducer级别并且忽略了这一点combineReducers().使用增强器,您可以将它们保存在一个位置(myRefStore).最后一个观察结果是,redux存储不是任何数据存储而是状态存储,因此我们需要在增强器中处理函数和其他非状态相关的东西.您可以利用Redux-Observable的增强器主干并myRefStore通过依赖注入.

  • 您的回答非常好,应该是公认的解决方案!由于您的示例,我能够以非常复杂的结构存储函数;) (2认同)