我应该如何基于它的当前状态在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
看起来很简单,但是当涉及到计算时,在不同的文件上编写相同的计算并不好。
答案 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);
}
});