as in React Hooks to give the initial value an empty object
Solution 1
Well, the thing that I found strange is that you pass Object
for useState hook.
export interface Y{
title: string;
name: string;
}
const [x, setX] = useState<Y>();
In that case the type of x is Y | undefined
, which is better as now we know that x is empty.
Passing Object
as you did will make typescript happy, but now you cheat on yourself as typescript won't guard you.
Depending on situation I would suggest to go the first route and leave useState empty, or hardcode object structure e.g.
const [x, setX] = useState<Y>({title: '', name: ''});
if the question is whether to use useReducer or useState - than I think it all depends on how often you are going to change the object. If the logic is simple enough using useReducer may be an overkill. Also, don't forget that useState is just a wrapper around useReducer hook, afaik.
Solution 2
const [x, setX] = useState<Y>(Object);
This is not valid typescript as the use of the generic parameter <Y>
makes the type system expect the initial state to be of type Y
(or null), making the only valid input, useState({ title: '', name: '' })
or useState(null)
Also, the useState hook does not perform partial updates on state.
export interface Y{
title: string;
name: string;
}
const [x, setX] = useState<Y>({ title: 'Mr', name: 'Jack' });
setX({ name: 'John' }) // <-- title: undefined
setX({ ...x, name: 'john' }) // <-- You will have to do this instead
Perfomance and reasoning wise this is okay for small objects, but when you have a large state object, state management gets hard. But breaking state into lots of variables makes code verbose. In that case, you can use a reducer hook.
Related videos on Youtube
Admin
Updated on June 04, 2022Comments
-
Admin almost 2 years
I have this code
export interface Y{ title: string; name: string; } const [x, setX] = useState<Y>(Object);
But my friends say that this is a bad idea. Why a bad idea to use this useState(Object)?
-
Avin Kavish almost 5 years
useState<Y>(Object);
What is this? Are you trying to pass the inbuilt Object prototype as the initial state value?. -
Admin almost 5 years@ Авин Кавиш var Object: ObjectConstructor .I myself do not understand what this means. But I get an empty object, the initial state.as I said, my friends scold me for such a cod but cannot explain why this is a bad idea.
-
Avin Kavish almost 5 yearsHow do you know you get an empty object?
-
Admin almost 5 years@Авин Кавиш Watch it. link
-
-
Admin almost 5 yearsmy question is this 1 What happens if you write like this
const [x, setX] = useState<Y>(Object)
; 2 Why am I not getting Error?3 difference between useState<Y>(); and useState<Y>(Object); -
Ruslan Abramov almost 5 years1. If we have a look at react type definition function
useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];
we see that accepts a function, so Object is considered as function and as you may guess the result of callingObject
is empty object{}
Note: just for fun try thisclass MyClass {}; const [x, setX] = useState(MyClass)
You will get an errorCannot call a class as a function
-
Admin almost 5 yearsI would like to hear the final answer use
useState <Y> (Object);
. This is the wrong way because it can lead to ......? -
Ruslan Abramov almost 5 yearsSorry, I think I've answered all of your questions. To sum it up - I consider this a bad idea to write
useState <Y> (Object);
cuz: 1 - you lose typesafety in typescript; 2 - this is not an obvious code. I bet that even an experienced developer will spend some time to understand what value will be in variablex
. And this is my personal advice: you write code for other developers that's why try to make it as readable as possible. If you think that this code leads to some perf issues and possible errors - than not, It is kinda safe.