在Redux Reducer中更新状态的正确方法

我是redux和es6语法的新手。我使用官方的redux教程和此示例制作了我的应用。

以下是JS代码段。我的观点-在post reducer中定义REQUEST_POST_BODY和RECEIVE_POST_BODY案例。主要困难-

在商店中查找和更新合适的对象。

我尝试使用示例中的代码:

  return Object.assign({}, state, {

[action.subreddit]: posts(state[action.subreddit], action)

})

但是它使用了简单的帖子数组。无需按ID查找正确的帖子。

这是我的代码:

  const initialState = {

items: [{id:3, title: '1984', isFetching:false}, {id:6, title: 'Mouse', isFetching:false}]

}

// Reducer for posts store

export default function posts(state = initialState, action) {

switch (action.type) {

case REQUEST_POST_BODY:

// here I need to set post.isFetching => true

case RECEIVE_POST_BODY:

// here I need to set post.isFetching => false and post.body => action.body

default:

return state;

}

}

function requestPostBody(id) {

return {

type: REQUEST_POST_BODY,

id

};

}

function receivePostBody(id, body_from_server) {

return {

type: RECEIVE_POST_BODY,

id,

body: body_from_server

};

}

dispatch(requestPostBody(3));

dispatch(receivePostBody(3, {id:3, body: 'blablabla'}));

回答:

带阵列

如果您想坚持使用数组,那么可以编写一个只处理单个post对象的reducer 。

export default function reducePost(post, action) {

if(post.id !== action.id) return post;

switch(action.type) {

case REQUEST_POST_BODY:

return Object.assign({}, post, { isFetching: true });

case RECEIVE_POST_BODY:

return Object.assign({}, post, { isFetching: false, body: action.body });

default:

return post;

}

您的根减速器将变为:

export default function posts(state = initialState, action) {

return state.map(post => reducePost(post, action);

}

我们只是对列表中的每个帖子运行新的reducer,以返回更新的帖子数组。在这种情况下,唯一ID将确保仅更改一项。

带物体

如果每个项目都有唯一的字符串/数字ID,则可以翻转数组并object改用。

const initialState = {

items: {

3: {id:3, title: '1984', isFetching:false},

6: {id:6, title: 'Mouse', isFetching:false}

};

}

然后,您可以简化减速器。

switch (action.type) {

case REQUEST_POST_BODY:

let id = action.id;

return Object.assign({}, state, {

[id]: Object.assign({}, state[id], { isFetching: true })

});

case RECEIVE_POST_BODY:

let id = action.id;

return Object.assign({}, state, {

[id]: Object.assign({}, state[id], {

isFetching: false,

body: action.body

})

});

default:

return state;

}

如果您也乐于尝试使用某些ES7语法,则可以使用Babel启用对象散布运算符,然后将重写为Object.assign

switch (action.type) {

case REQUEST_POST_BODY:

let id = action.id;

return {

...state,

[id]: {...state[id], isFetching: true }

};

case RECEIVE_POST_BODY:

let id = action.id;

return {

...state,

[id]: {

...state[id],

isFetching: false,

body: action.body

}

};

default:

return state;

}

如果您不太热衷于使用传播语法,那么仍然可以使它Object.assign更加美味。

function $set(...objects) {

return Object.assign({}, ...objects);

}

case RECEIVE_POST_BODY:

let id = action.id;

return $set(state, {

[id]: $set(state[id], {

isFetching: false,

body: action.body

})

});

以上是 在Redux Reducer中更新状态的正确方法 的全部内容, 来源链接: utcz.com/qa/422414.html

回到顶部