如何从额外的减速器添加案例中更改另一个减速器的状态

How can I change state of another reducer from extra reducers add cases

我正在尝试创建一个通知组件。 我的通知组件处于根级别,每当用户尝试登录时,异步函数的过程都会转发给他,即等待完成或拒绝。

问题是我不知道如何从 userSlice 调用 notification reducer,或者即使可能,这是否是一个好方法。

用户切片

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";

const initialUserState = { 
    currentUser:null 
}

export const getUser = createAsyncThunk(
    'user/getUser',
    async (endpoint, data) => {
        return(
            await axios.post(endpoint, data)
            .then(res =>{
                return res.data.user
            })
            .catch(error =>{
                throw Error(error.response.data)
            })
        )
    }
)

const userSlice = createSlice({
    name: 'user',
    initialState: initialUserState,
    reducers:{
        currentUser(state, action){
            state.currentUser = action.payload
        }
    },
    extraReducers: 
        (builder) => {
            builder.addCase(getUser.pending, ()=>{
                console.log("authing")
            })
            builder.addCase(getUser.fulfilled, (state, action)=>{
                state.currentUser = action.payload
                console.log("fulfilled")
            })
            builder.addCase(getUser.rejected, (state, action)=>{
                console.log("failed")
                alert(action.error.message)
            })
        }
})

export const userActions = userSlice.actions;
export default userSlice.reducer;

notificationSlice

import React from 'react'
import { useSelector } from 'react-redux'

function Notification() {

    const toast = useSelector(state => state.notification)
    console.log(toast)
    return (
        toast.active &&
        <div className="notification" style={{backgroundColor:toast.backgroundColor}} >
            {toast.message}
        </div>
    )
}

export default Notification

我想在调用 userSlice 中的 extra reducer 之一时更改 通知状态

我认为您几乎完全在倒退地思考这个问题。您想要的不是“从 userSlice 调用通知缩减器”,而是在 notificationSlice.

中监听 userSlice 操作

我做了类似下面的事情,我认为这对你很有效:

import { createEntityAdapter, createSlice, isAnyOf } from '@reduxjs/toolkit'

const notificationsAdapter = createEntityAdapter()

const initialState = notificationsAdapter.getInitialState({
  error: null,
  success: null,
})

const notificationsSlice = createSlice({
  name: 'notifications',
  initialState,
  reducers: {
    clearNotifications: state => {
      state.error = null
      state.success = null
    },
    setError: (state, action) => {
      state.success = null
      state.error = action.payload
    },
    setSuccess: (state, action) => {
      state.success = action.payload
      state.error = null
    },
  },
  extraReducers: builder => {
    builder
      .addMatcher(
        isAnyOf(
          getUser.fulfilled,
        ),
        (state, action) => {
          state.error = null
          state.success = action.payload.message
        }
      )
      .addMatcher(
        isAnyOf(
          getUser.rejected
          // can add as many imported actions
          // as you like to these
        ),
        (state, action) => {
          state.error = action?.payload
          state.success = null
        }
      )
      // reset all messages on pending
      .addMatcher(
        isAnyOf(
          getUser.pending
        ),
        (state, action) => {
          state.error = null
          state.success = null
        }
      )
  },
})
export const { clearNotifications, setError, setSuccess } = notificationsSlice.actions

export default notificationsSlice.reducer

export const getErrorMsg = state => state.notifications.error
export const getSuccessMsg = state => state.notifications.success

添加了以上内容后,您现在可以创建一个监听

的通知组件
  const error = useSelector(getErrorMsg)
  const success = useSelector(getSuccessMsg)

并相应地显示消息。

警告:

  • 我的 notificationSlice 代码假定当一个动作完成时,成功负载上将存在一个“消息”对象。因此,在我的异步 thunk 上,如果我的 api 没有 return 这个我必须明确地将这个添加到结果中。