【问题标题】:Why can't I push in this dispatch action?为什么我不能推送这个调度动作?
【发布时间】:2021-02-02 15:32:20
【问题描述】:

我正在创建一个聊天室应用程序,目前我只是在关闭本地功能。我创建了一个测试对象来保存聊天室数据,包括消息。现在,我有一个用于聊天的文本输入字段,但我似乎无法访问我的聊天室对象中的消息以将新消息推送到其中。当我控制台记录 state.messages 时,我似乎得到了这个奇怪的代理对象而不是消息数组。有人知道为什么吗?这是我的代码:

JSX:

<InputGroup className="mb-3">
            <FormControl aria-describedby="basic-addon1" className="chat-insert"/>
            <InputGroup.Append>
                <Button variant="outline-secondary" onClick={() => {
                    dispatch(addChat(document.querySelector('.chat-insert').value));
                    document.querySelector('.chat-insert').value = '';
                }}>Send</Button>
           </InputGroup.Append>
</InputGroup>

数据对象:

let chatData = [
    {
        name: "General Chatroom",
        private: false,
        passcode: null,
        currentUsers: [],
        messages: [
            {
                avatar: "#",
                username: 'Chatter[bot]',
                message: `Welcome to Chatter[box]! This is the beginning of this chatroom's history!`
            },
        ]
    }
]

export default chatData

减速机:

import { createSlice } from '@reduxjs/toolkit'
import chatData from '../../components/chatData'

export const chatSlice = createSlice({
    name: 'chat',
    initialState: chatData[0],
    reducers: {
        addChat: (state, action) => {
            console.log(chatData[0])
            state.messages.push({
                avatar: "#",
                username: "",
                message: action.payload
            })
            console.log(state.messages)
        },
    },
});

export const { addChat } = chatSlice.actions

export const selectChat = state => state.messages

export default chatSlice.reducer

控制台日志:

【问题讨论】:

  • 状态是不可变的。你不应该在减速器中使用Array.prototype.push。您应该使用扩展运算符 ...state.messages 复制 state.messages 改为一个新数组。
  • 浅拷贝现有状态,浅拷贝数组,然后将新元素添加到数组中,不要忘记从reducer函数返回你的新状态对象。
  • 我怀疑您将 javascript Proxy 对象视为 redux 实现细节,因为您正在控制台记录内部、中间“状态”与减速器 应该*/*会 i> 返回。

标签: javascript reactjs react-redux jsx


【解决方案1】:

Redux Toolkit 中的createSlice 函数使用Immer 库来允许编写直接修改状态的reducer。您的 reducer 中的 state 对象是您当前状态的“草稿状态”代理。

要快照和打印“草稿状态”,请使用 Redux Toolkit 从 Immer 重新导出的 current 函数。以下是来自Logging Draft State Values 的示例:

import { createSlice, current } from '@reduxjs/toolkit'

const slice = createSlice({
  name: 'todos',
  initialState: [{ id: 1, title: 'Example todo' }],
  reducers: {
    addTodo: (state, action) => {
      console.log('before', current(state))
      state.push(action.payload)
      console.log('after', current(state))
    },
  },
})

【讨论】:

    猜你喜欢
    • 2011-09-03
    • 2020-12-05
    • 1970-01-01
    • 2012-11-25
    • 2016-01-10
    • 2020-02-21
    • 2023-02-06
    • 1970-01-01
    • 2013-01-26
    相关资源
    最近更新 更多