Component For Either Creating Or Editing The User
A part of the code below where I am setting the isActive
state conditionally inside useEffect
I am getting the other fields of user_data
and successfully updating the state
but only setIsActive
is not updating the state
function CreateUser() {
const [isActive, setIsActive] = useState<boolean | undefined>();
useEffect(() => {
if (params_user_id?.id != null) {
const SINGLE_USER_URL = `users/${params_user_id.id}/edit`;
const getSingleUser = async () => {
const {data} = await axios.get(SINGLE_USER_URL)
console.log(data)
setIsActive(data.isactive)
console.log('isactive', isActive)
}
getSingleUser();
}
}, [params_user_id])
return (
<>
<Form.Check
defaultChecked={isActive}
className='mb-3'
type='checkbox'
id='active'
onChange={e => setIsActive(!(isActive))}
label='Active: Unselect for deleting accounts.'/>
</>
)
}
Form.Check From Bootstrap-React
When I hit the Edit page
I did try many things like ternary operator
etc
checkBox
is not checked
bcoz it's undefined
CodePudding user response:
Setting the state in React acts like an async function.
Meaning that the when you set the state and put a console.log
right after it, it will likely run before the state has actually finished updating.
Which is why we have useEffect
, a built-in React hook that activates a callback when one of it's dependencies have changed.
In your case you're already using useEffect
to update the state, but if you want to act upon that state change, or simply to log it's value, then you can use another separate useEffect
for that purpose.
Example:
useEffect(() => {
console.log(isActive)
// Whatever else we want to do after the state has been updated.
}, [isActive])
This console.log
will run only after the state has finished changing and a render has occurred.
- Note: "isActive" in the example is interchangeable with whatever other state piece you're dealing with.
Check the documentation for more info about this.
Additional comments:
Best to avoid using the loose
!=
to check for equality/inequality and opt for strict inequality check instead, i.e. -!==
Loose inequality is seldom used, if ever, and could be a source for potential bugs.Perhaps it would better to avoid typing this as
boolean | undefined
.
Unless justified, this sounds like another potential source for bugs.
I would suggest relying on justboolean
instead.
CodePudding user response:
First, you can't get the state's updated value immediately after setting it because State Updates May Be Asynchronous
useEffect(() => {
if (params_user_id?.id != null) {
const SINGLE_USER_URL = `users/${params_user_id.id}/edit`;
const getSingleUser = async () => {
const {data} = await axios.get(SINGLE_USER_URL)
console.log(data)
setIsActive(data.isactive)
console.log('isactive', isActive) // <-- You can't get updated value immediately
}
getSingleUser();
}
}, [params_user_id])
Change the type of useState
to boolean
only and set the default value to false
.
const [isActive, setIsActive] = useState<boolean>(false);
Then, in Form.Check
, update onChange
to this:
<Form.Check
defaultChecked={isActive}
className='mb-3'
type='checkbox'
id='active'
onChange={() => setIsActive((preVal) => !preVal)}
label='Active: Unselect for deleting accounts.'
/>