Can you use useState variable_1 as default value for another useState variable_2, especially when variable_1 is being set by useEffect?
Even simpler, can you use useState variable_1 as default value for another useState variable_2 (without the useEffect dependency)?
To elaborate, here's an example
const [firstName, setFirstName] = useState("DEFAULT_NAME");
const [fullName, setFullName] = useState(firstName); //is doing this permissible?
useEffect(() => {
setFirstName("REAL_NAME")
}, []);
console.log(fullName); // what would be printed here?
What would the value of fullName be? Would it be set to "DEFAULT_NAME" (signaling that it was set BEFORE the useEffect was called) or be set to "REAL_NAME" (signaling that it was set AFTER the useEffect was called)?
CodePudding user response:
React components with hooks it's just a function, it executes from top to bottom; useEffect won't fires when React is ready to update it's view, it doesn't interfere with the useState initialization.
So you can do that, there's no problem. But, as @CertainPerformance mentioned at the end, it's better to just separate the defaultValue on a separate variable.
BTW, on this line:
const [fullName, setFullName] = useState(firstName);
fullName is going to be "DEFAULT_NAME" based on your example.
and here as well:
console.log(fullName); // what would be printed here?
CodePudding user response:
You can, but it usually wouldn't be a good idea. What'll happen is the second variable will be initialized to be the same as the first, but after that, they'll be completely disconnected from each other; updating either of the states later would not result in the other state changing.
Usually, in a situation where you might be thinking about something like this, it'd be better to have only a single state, with the dependent value calculated inside component (perhaps with useMemo for efficiency's sake), eg
const [firstName, setFirstName] = useState("DEFAULT_FIRST_NAME");
const [lastName, setLastName] = useState("DEFAULT_LAST_NAME");
const fullName = useMemo(() => firstName ' ' lastName, [firstName, lastName]);
You don't want to do, eg
const [firstName, setFirstName] = useState("DEFAULT_FIRST_NAME");
const [capitalizedName, setCapitalizedName] = useState(firstName);
// ...
onChange=(e => {
setFirstName(e.target.value);
setCapitalizedName(e.target.value.toUpperCase());
})
It's messy to have state data duplicated in more than one state variable, and it can be confusing - you don't want to call a couple of state setters when updating only a single value.
But if the logic you're looking for doesn't require that - if you really only care to initialize both states to the same thing on mount, and have them be completely separate afterwards - then what you're doing now would be just fine.
Though, I'd consider it to be a bit clearer if both default values referenced the same outer variable:
const defaultName = "DEFAULT_NAME";
const [firstName, setFirstName] = useState(defaultName);
const [fullName, setFullName] = useState(defaultName);
That has less chance of confusing readers.
