Reputation: 2115
I'm trying to learn how React hooks work with a simple authentication modal that I've set up. I have a custom useForm
hook that handles form state, and I'm curious as to how I have access to values
before it's declared.
function LoginModal () {
console.log('outside values', values) // undefined
const submitForm = async () => {
console.log('inside values', values) // email, password values exist
const request = {
method: 'POST',
url: '/auth/login',
data: {
email: values.email,
password: values.password
}
}
await axios(request)
}
const [values, handleChange, handleSubmit] = useForm(submitForm)
return <div>some form stuff</div>
}
`useForm.js`
import { useState } from 'react'
const useForm = submitForm => {
const [state, setState] = useState({})
const handleChange = event => {
event.persist()
setState(state => ({ ...state, [event.target.name]: event.target.value }))
}
const handleSubmit = event => {
event.preventDefault()
submitForm()
}
return [state, handleChange, handleSubmit]
}
export default useForm
Can someone explain to me why values
exist only within the submitForm
function, and how it's available before const [values]
is even declared? I believe const
declarations aren't hoisted. Thanks!
Upvotes: 3
Views: 1977
Reputation: 31495
When you declare a function JS will keep that function declaration in memory and will give access the its respective local and global scope. This is what happens to your submitForm
function. In the example from the snippet below, this is the someFunc
function.
As you can see form the example below, if you execute that function before the variable values
has been declared, you'll get undefined
. Because it's not in scope yet.
But if you execute the function through a click event like you're doing, after the variable values
has been defined, your function will be able to 'see' the variable because it's already in scope.
NOTE: You're correct. const
declarations are not hoisted.
function App() {
// WHEN YOU CALL IT THROUGH A CLICK EVENT, THE VARIABLE `values` WILL BE IN SCOPE
function someFunc() {
console.log('State from someFunc(): ' + values);
}
console.log('State from component body BEFORE variable "values" declaration: ' + values);
someFunc(); // WHEN EXECUTED AT THIS POINT. IT HAS NO ACCESS TO 'values' BECAUSE IT'S STILL undefined
const [values,setValues] = React.useState(['a','b','c']);
console.log('State from component body AFTER variable "values" declaration: ' + values);
return(
<button onClick={someFunc}>Click to run someFunc()</button>
);
}
ReactDOM.render(<App/>,document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Upvotes: 3