【问题标题】:How to update the state in React Redux?如何更新 React Redux 中的状态?
【发布时间】:2021-10-29 13:26:50
【问题描述】:

我正在使用 reducer 在 Redux 中设置状态。我的状态目前看起来像这样。

{
  activeConversation: "Jim"
  conversations: (7) [{…}, {…}, {…}, {…}, {…}, {…}, {…}]
  user: {id: 8, username: "josh", email: ""}
}

在我的旧减速器中,我只是获取对话数组并进行设置,但现在我还需要访问 activeConversation 字符串。因此,我决定使用我的根减速器,它结合了所有内容,以便它可以正常工作。这是我的根减速器。

import { createStore, applyMiddleware, combineReducers } from "redux";
import loggerMiddleware from "redux-logger";
import thunkMiddleware from "redux-thunk";

import user from "./user";
import conversations from "./conversations";
import activeConversation from "./activeConversation";
import {
addMessageToStore,
} from "./utils/reducerFunctions";

const CLEAR_ON_LOGOUT = "CLEAR_ON_LOGOUT";
const SET_MESSAGE = "SET_MESSAGE";

export const clearOnLogout = () => {
  return {
    type: CLEAR_ON_LOGOUT
  };
};

export const setNewMessage = (message, sender) => {
  return {
    type: SET_MESSAGE,
    payload: { message, sender: sender || null },
  };
};

const appReducer = combineReducers({
  user,
  conversations,
  activeConversation
});
const rootReducer = (state, action) => {
  if (action.type === CLEAR_ON_LOGOUT) {
    state = undefined;
  } else if (action.type === SET_MESSAGE) {
    return addMessageToStore(state, action.payload);
  }
  return appReducer(state, action);
};

export default createStore(rootReducer, applyMiddleware(thunkMiddleware, loggerMiddleware));

我的 setNewMessage 函数被调用,然后调用addMessageToStore

export const addMessageToStore = (state, payload) => {
  const { message, sender } = payload;
  return { ...state, conversations: state.conversations.map((convo) => {
    if (convo.id === message.conversationId) {
      const newUnread = convo.unreadMessages;
      if (state.activeConversation === convo.otherUser) {
        newUnread = (parseInt(newUnread) + 1).toString();
      }
      const newConvo = {
        ...convo,
        messages: convo.messages.concat(message),
        latestMessageText: convo.latestMessageText,
        unreadMessages: newUnread
      }
      console.log("newConvo:", {...state, conversations: newConvo});
      return {...state, conversations: newConvo};
    } else {
      return {...state, conversations: convo};
    }
  })};
};

问题在于next state 没有更新。当它返回next state 时,它只显示以前的状态而不是我的新状态。有谁知道怎么回事?

【问题讨论】:

    标签: javascript reactjs redux react-redux state


    【解决方案1】:

    我认为您正在“削减”您的状态切片效率低下。充其量,Reducer 应该始终拥有自己的状态,而您现在正竭尽全力为conversations 提供元reducer 以访问activeConversation

    为什么不为两者都配备一个普通的减速器?

    有一个形状的状态

    {
      user,
      conversations
    }
    

    conversations 的形状在哪里

    {
      items,
      active
    }
    

    这样,您的 conversations 减速器只需访问它自己的状态属性 - itemsactive - 并且不需要任何体操。

    【讨论】:

    • 另外,请看一下官方的 Redux 文档——你通常在这里写一个非常古老的 Redux 风格。 Modern Redux 大约是您在此处编写的代码的四分之一,并且使用起来更加舒适。 redux.js.org/tutorials/essentials/part-1-overview-concepts
    • 我实际上确实有一个用于会话和 activeConversation 的减速器,但问题是我不知道如何在我的会话减速器中获取 activeConversation 的值。
    • 这就是为什么我的意思是“将两者放在同一个减速器中”。一个 reducer 可以包含尽可能少或尽可能多的数据 - 显然这些数据是相互关联的,因此将其拆分为多个 reducer 只会让您头疼。 Redux 文档建议每个功能使用一个 reducer 切片,而不是每个数据值。只有原子数据会使 Reducer 变得毫无意义。
    【解决方案2】:

    我猜这与:

    return { ...state, conversations: state.conversations.map((convo) => {
        // ...
            return {...state, conversations: newConvo};
        } else {
            return {...state, conversations: convo};
        }
     }
    

    对于每个对话,您最终会得到整个状态的克隆,但 conversations 键换成了单个对话(例如 {state: { conversations: [ { state: { conversations: convo } } ] }

    你应该这样做

     return { ...state, conversations: state.conversations.map((convo) => {
        // ...
            return newConvo;
        } else {
            return convo;
        }
     }
    

    【讨论】:

    • 我已经尝试过了,但没有成功。以前,我的 return 语句过去常说 return state.conversations.map,但这会导致很多问题,因为 next state 被设置为会话数组而不是整个状态。
    • 你完全错过了我在说什么。您的 top 级别回报包括该州的其余部分。现在,您将它包含在 map 函数的返回中。
    猜你喜欢
    • 1970-01-01
    • 2020-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-21
    • 2019-05-30
    • 1970-01-01
    • 2021-02-15
    相关资源
    最近更新 更多