[英]Can I use condition in my action reducer?
基本上,在我們的例子中,我們需要獲得一個警報列表,顯示前幾個項目(首次在DOM中安裝)或顯示初始列表+下一個列表(單擊load more
按鈕)。
因此,我們需要在GET_ALERTS
操作中執行此操作:
case "GET_ALERTS":
if (action.initialList) {
newState.list = [...newState.list, action.res.data.list];
} else {
newState.list = newState.list.concat(
action.res.data.list
);
}
當我們在Alerts組件中調用action reducer時,我們需要指出initialList
是true還是false。
例如
componentDidMount() {
this.props.getAlerts(pageNum, true);
}
markAllAsRead() {
// other code calling api to mark all as read
this.props.getAlerts(pageNum, false);
}
readMore() {
// other code that increases pageNum state counter
this.props.getAlerts(pageNum, true);
}
無論如何在這種情況下,在reducer中使用條件語句是否可以?
我反對這個想法。 reducer有一個責任:根據操作更新Redux狀態。
以下是解決這個問題的三種方法:
如果你將state
列表設置為空列表( []
)那么它就更簡單了。 您基本上只需將減速器更改為:
case "GET_ALERTS":
return {...state, list: [...state.list, action.res.data.list]
這將確保即使您已獲得要添加到列表的初始列表或更多項目,它們也將被追加。 無需添加任何邏輯 - 這是真棒恕我直言。
創建兩個動作: GET_INIT_ALERTS
和GET_MORE_ALERTS
。
switch(action.type) {
case "GET_INIT_ALERTS":
return {...state, list: action.res.data.list }
case "GET_MORE_ALERTS":
return {...state, list: [...state.list, ...action.res.data.list]}
case "CHECK_READ_ALERTS":
return {...state, read: [...state.read, ...action.res.data.list]}
}
在組件我將:
componentDidMount() {
this.props.getInitAlerts();
}
markAllAsRead() {
// other code calling api to mark all as read
this.props.getAlerts(pageNum, false);
}
readMore() {
// other code that increases pageNum state counter
this.props.getAlerts(pageNum);
}
在redux-thunk的幫助下進行警報操作:
export const getAlerts = (pageNum : number) => (dispatch) => {
return apiAction(`/alerts/${pageNum}`, 'GET').then(res => dispatch({type: "GET_MORE_ALERTS", res});
}
export const getInitAlerts = () => (dispatch) => {
return apiAction('/alerts/1', 'GET').then(res => dispatch({type: "GET_INIT_ALERTS", res});
}
我猜你在readMore
或componentDidMount
之后更新pageNum
。 當然,您可以將該狀態保存在Redux中並將其映射回props,並在調用getAlerts
操作時將其遞增。
另一種方式做,這是寫的ad-hoc /功能的中間件concat
新數據的列表。
const concatLists = store => next => action => {
let newAction = action
if (action.type.includes("GET") && action.initialList) {
newAction = {...action, concatList: action.res.data.list}
} else if (action.type.includes("GET") {
newAction = {...action, concatList: [...state[action.key].list, action.res.data.list]}
}
return next(newAction);
}
並更改您的reducer以簡單地將concatList
推concatList
狀態:
case "GET_ALERTS":
return {...state, list: action.concatList}
此外,您必須將操作更改為包含key
(在這種情況下,密鑰將設置為alert
(或在redux中存儲警報狀態的密鑰的名稱)和initialList以確定是否連接。
順便說一下,把這兩個放在meta
鍵下是一個好習慣。
{
type: "GET_ALERT",
meta: {
initialList: true,
key: "alert",
},
res: {...}
}
我希望這有幫助。
我建議你采取以下行動:
商店結構
{
list: [],
currentPage: 0
}
組件代碼不應跟蹤pageNum
componentDidMount() {
this.props.initAlerts();
}
markAllAsRead() {
this.props.markAllAsRead();
}
readMore() {
this.props.loadMore();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.