如何从额外的减速器添加案例中更改另一个减速器的状态
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 这个我必须明确地将这个添加到结果中。
我正在尝试创建一个通知组件。 我的通知组件处于根级别,每当用户尝试登录时,异步函数的过程都会转发给他,即等待完成或拒绝。
问题是我不知道如何从 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
.
我做了类似下面的事情,我认为这对你很有效:
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 这个我必须明确地将这个添加到结果中。