当前位置: 首页 > 面试题库 >

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

邵博远
2023-03-14
问题内容

我是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
    })
  });


 类似资料:
  • 我在UI中有一个按钮,在OnClick事件处理程序中,我必须运行一个设置间隔计时器。在设置间隔计时器中,我检查一个条件,如果条件满足,我将更新状态,但它不能正常工作。 00); 在倒计时功能中有一个console.log,它总是打印“0 false”,但UI中的组件网正在更新为正确的数字。 你能告诉我为什么吗 控制台中的计数始终为“0”。log 代码沙盒链接:https://codesandbox

  • 问题内容: 抱歉,我真的很想念React中子组件内部的传递。 我已经实现了一个包含3个组件的待办事项列表。 有一个组成部分和一个组成部分。状态仅存储在组件中。 显示器起步不错,因此可以看到道具。但是在提交表单后,我收到了以下错误: TypeError:this.props.tasks.map不是函数 当我console.log时,我没有得到我的数组,而是数组的长度。 你知道为什么吗? 编辑 :谢谢

  • 招呼: 我认为我没有正确更新我的复杂状态: 如何正确更新此状态?谢谢 https://codesandbox.io/s/intelligent-ellis-qi97k?file=/src/App.js

  • 我有3个div。当我点击特定的按钮时,每个人都会有类活动。它们的每个div都有一个状态变量,每当它是真的时,我都会向连接到它的div添加class Name='active': 当我点击按钮时,状态改变,但是div没有激活类 当我将函数更改为此时,它会工作: ================================================ =====================

  • 我正在开发一个小待办事项应用程序,作为使用React的练习。我有一个这样的模拟服务: 在我的React应用程序中,我有一些包含TODO的状态: 是一个函数,我将它传递到我的组件中,当我想完成这样一个Todo时使用: 因此,每当用户单击复选框并使用调用时,就会从服务对象中删除它,并且状态应该更新,但最奇怪的事情发生了。 当调用时,todo将被正确删除,但当调用时,旧的todo仍然存在!如果我将内容写

  • 我通过使用map函数迭代来显示我的状态,这是一个数组。此外,我有一个按钮,在点击反转数组。 我认为我想做什么是相当明显的。但这对我不起作用,我不知道为什么。我必须单击两次来完成第一次还原,出现了奇怪的情况,即呈现的数组和Chrome中React开发工具在组件状态中显示的数组不匹配。 我无法解释这种行为。我开始认为这与我从道具中获得阵列有关,但我真的不知道。有什么想法吗?