When using console.log()
inside a reducer action, the state prints as a Proxy object, instead of the object I actually want to see. How do I see the actual object? I am using redux-starter-kit createSlice, I am not sure if this has anything to do with it.
import { createSlice } from "redux-starter-kit";
export interface IToDo {
id: number;
name: string;
complete: boolean;
}
const initialState: IToDo[] = [
{
id: 1,
name: 'Read a bit',
complete: true
}
];
const { actions, reducer } = createSlice({
slice: "todos",
initialState,
reducers: {
toggleTodo(state: IToDo[], action) {
const todo = state.find(todo => todo.id === action.payload);
console.log(todo);
if (todo) {
todo.complete = !todo.complete;
}
}
}
})
export const toDosReducer = reducer;
export const { toggleTodo } = actions;
This is the output I see in the console when I toggle my ToDo:
You need to use the current
function in order to see the actual value of the state.
In your reducer, you can call:
console.log(current(state));
This current
function comes from the Immer package which is a dependency of Redux Toolkit. It is re-exported by Redux Toolkit, so it can be imported from either package:
import { createSlice, current } from '@reduxjs/toolkit';
or
import { createSlice } from '@reduxjs/toolkit';
import { current } from 'immer';
Proxy
?Redux Toolkit's createSlice
and createReducer
helper functions allow you to write reducers where you directly modify the state
variable. This can save a lot of code and a lot of headaches compared to writing reducers the traditional way, where you must always return a new state object and cannot mutate any values of your state.
It is okay to "mutate" the state
variable in a Redux Toolkit reducer because this state
variable is not your actual state. It is a Proxy
object. Specifically, it is a Immer draft.
The basic idea is that with Immer you will apply all your changes to a temporary draft, which is a proxy of the currentState. Once all your mutations are completed, Immer will produce the nextState based on the mutations to the draft state. This means that you can interact with your data by simply modifying it while keeping all the benefits of immutable data.
For further reading, see:
current()
?The current
function is a way to access the current state of the draft object for debugging. Otherwise, you would see the draft itself which is a Proxy
and that's not very helpful. You probably won't ever use current
for anything other than console logging.
This function is part of the Immer package and it is re-exported by Redux Toolkit specifically for this purpose.
current
The current function from the immer library, which takes a snapshot of the current state of a draft and finalizes it (but without freezing). Current is a great utility to print the current state during debugging, and the output of current can also be safely leaked outside the producer.
For further reading, see: