reduxjs/redux

react-redux@9.0.1: Empty object check error

zhe-he opened this issue · 4 comments

zhe-he commented

https://github.com/reduxjs/redux/blob/0e8a7b00db58796f7a7adef6ac9ebed9420c18cb/src/utils/isPlainObject.ts#L5C1-L14C2
image

I just upgraded the package to @reduxjs/toolkit@2.0.1 and react-redux@9.0.1 today, and then I found that the console reported an error, A non-serializable value was detected in the state, in the path. Finally, I found that it was because the object I created through Object.create(null) did not pass the isPlainObject function check. I want to know if this is correct, um... Do not want users to use objects created by Object.create(null) or is this function check not comprehensive enough?

console.log( {} ) // true
console.log( isPlainObject(Object.create(null)) ) // false ???

Out of curiosity, what's the use case for Object.create(null) here? What are you doing with it in code?

zhe-he commented

I use it just to create an empty object for storing data, and later I will add keys and values to this empty object. In some cases, it just makes it convenient for me to have fewer declarations, for example, declaring AnyObject explicitly.

const data = Object.create(null);
data.a = 1;

const data: AnyObject = {};
data.a = 1;

@zhe-he : I'm okay with merging the fix, but tbh I'm not sure I see an actual reason to use Object.create(null) here :) the AnyObject example is actually shorter, and also more clear about what's going on.

zhe-he commented

Well..., I'm not trying to convince you which method is better, I think any method is fine, it's just based on my personal habits.
I don't like explicit declarations, so I used the any returned by Object.create. At the same time, I personally think that the Object.create(null) loop will be a bit faster, so I used this, below is the time spent on testing.

image
// 2 lines
import { AnyObject } from "@/@types";
const data: AnyObject = {};

// 1 line
const data = Object.create(null);


// 2 lines or 9 lines
export type M = {
    name: string;
    value: string;
    child?: M[];
}
export type O = {
    [props: string]: M
}
// import { O } from "@/@types";
const map: O = {}

// 1 line
const map = Object.create(null);