我正在尝试学习 React 钩子如何使用我设置的简单身份验证模式。我有一个处理表单状态的自定义useForm
钩子,我很好奇如何在声明之前访问values
。
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
有人可以向我解释为什么values
只存在于submitForm
函数中,以及在声明const [values]
之前它是如何可用的?我相信const
声明不会被吊起来。谢谢!
当你声明一个函数时,JS会将该函数声明保存在内存中,并将提供其各自的本地和全局范围的访问权。这就是您的submitForm
函数发生的情况。在下面代码片段的示例中,这是someFunc
函数。
正如您在下面的示例中看到的,如果您在声明变量 values
之前执行该函数,您将获得undefined
。因为它还没有在范围内。
但是,如果您像现在这样通过单击事件执行函数,则在定义变量values
后,您的函数将能够"看到"该变量,因为它已经在范围内。
注意:你是对的。 const
申报不被悬挂。
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>