redux如何获取或存储计算值

时间:2016-07-13 04:33:40

标签: javascript reactjs redux

我应该如何基于它的当前状态在redux计算值中实现?

我有一个例子,一个sessionState

const defaultState = {
  ui: {
    loading: false
  }, metadata: { },
  data: {
    id: null
  }
}

export default function sessionReducer(state = defaultState, action) {
  switch(action.type) {
  case STORE_DATA:
    return _.merge({}, state, action.data);
  case PURGE_DATA:
    return defaultState;
  default:
    return state;
  }
}

比如说我希望如果会话已登录,我现在通常会sessionState.data.id检查它,但我想知道我可以做sessionState.loggedIn或其他什么?< / p>

这可以吗?

const defaultState = {
  ui: {
    loading: false
  }, metadata: { },
  data: {
    id: null
  },
  loggedIn: () => {
    this.data.id
  }
}

或其他东西(未经测试,只是把它扔进去)。在这个例子中,只是编写.data.id看起来很简单,但是当涉及到计算时,在不同的文件上编写相同的计算并不好。

2 个答案:

答案 0 :(得分:2)

向状态对象添加方法是个坏主意。国家应该是普通的对象。请记住,有些库会在每个突变上序列化应用程序状态。

您可以在州对象之外创建计算功能。他们可以接受国家作为论据。他们为什么要成为州的方法?

const defaultState = {
  ui: {
    loading: false
  }, metadata: { },
  data: {
    id: null
  }  
}


 const loggedIn = (state) => {
   //your logic here
 }

答案 1 :(得分:1)

在您的特定示例中,计算结果非常简单且计算速度非常快,因此您可以每次按需计算结果。这样可以很容易地定义某个函数来计算它,就像@Lazarev建议的那样。

但是,如果您的计算变得更加复杂和耗时,您将希望将结果存储在某处,以便您可以重复使用它。将这些数据置于状态并不是一个好主意,因为它会使状态非正规化。

幸运的是,由于状态是不可变的,你可以编写一个简单的纯函数来计算结果,然后你可以使用memoization来缓存结果:

const isLoggedIn = memoize(state => state.login.userName && state.login.token && isValidToken (state.login.token));

最后,如果您想在商店状态下使用方法,可以使用Redux Schema(免责声明:我写过):

const storeType = reduxSchema.type({
  ui: {
    loading: Boolean
  }, metadata: { },
  data: {
    id: reduxSchema.optional(String)
  },
  loggedIn() {
    return Boolean(this.data.id);
  }
});