就我们而言,基本上,我们需要获取一个警报列表,以显示前几个项目(在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组件中调用动作减少器时,我们需要指出initialList
是对还是假。
例如
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中使用条件语句是否可以?
答案 0 :(得分:5)
我反对这个主意。 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});
}
我猜您是在pageNum
或readMore
之后更新componentDidMount
。当然,您可以将该状态保存在Redux中,并将其映射回道具,并在调用getAlerts
操作时将其递增。
另一种方法是将临时/功能中间件写入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
推入状态:
case "GET_ALERTS":
return {...state, list: action.concatList}
此外,您必须将操作更改为包含key
(在这种情况下,密钥将设置为alert
(或在redux中存储警报状态的密钥名称) )和initialList以确定是否合并。
顺便说一句,将这两个放在meta
键下是一个好习惯。
{
type: "GET_ALERT",
meta: {
initialList: true,
key: "alert",
},
res: {...}
}
我希望这会有所帮助。
答案 1 :(得分:0)
我建议您采取以下行动:
商店结构
{
list: [],
currentPage: 0
}
并且组件代码不应跟踪pageNum
componentDidMount() {
this.props.initAlerts();
}
markAllAsRead() {
this.props.markAllAsRead();
}
readMore() {
this.props.loadMore();
}