我正在尝试了解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
声明不会被悬挂。谢谢!
答案 0 :(得分:1)
当您声明一个函数时,JS将把该函数声明保留在内存中,并提供对其各自本地和全局范围的访问。这就是您的submitForm
函数所发生的事情。在下面摘录的示例中,这是someFunc
函数。
从下面的示例中可以看到,如果在声明变量values
之前执行,将得到undefined
。因为它不在范围内。
但是,如果您像执行操作一样通过click事件执行函数,则在定义变量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>