微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 React 中导入组件时出现无效的钩子调用错误

如何解决在 React 中导入组件时出现无效的钩子调用错误

我建立了一个登录页面,在填写用户名和密码并点击提交按钮时,它会分派基本上转到后端并检查用户名和密码是否有效的操作。我正在使用 Reactredux,这是我下面的登录页面

login.js(简化版)

import LoginHandle from '../login/LoginHandle'

function userLogin(event) {
  event.preventDefault()
  const username = document.getElementById("username").value
  const password = document.getElementById("password").value
  
  LoginHandle(username,password)

}

const Login = () => {
  return (
    <div className="flex-row align-items-center">
                  <form onSubmit={(e) => userLogin(e)}>
                    <h1>Login</h1>
                    
                      <input id="username" type="email" placeholder="Username" required/>
                 
                      <input id="password" type="password" placeholder="Password" required/>
      
                        <button type="submit" className="px-4">Login</button>
                </form>
    </div>
  )
}

export default Login

LoginHandle.js(简化版)

import {usedispatch,useSelector} from 'react-redux'
import {getLoginStatus} from '../actions/loginAction'


const LoginHandle = (username,password) => {

    const dispatch = usedispatch()
    dispatch(getLoginStatus(username,password))
    const loginState = useSelector(state=> state.loginStatus) 

    if(loginState.loading) {
        console.log("please wait")
    }

    // .... rest of the logic
}

export default LoginHandle

如您所见,我尝试发送操作,然后检查状态以从后端获得确认。但是我收到这个错误

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This Could happen for one of the following reasons:...

我做错了什么?

解决方法

import {useDispatch,useSelector} from 'react-redux'
import {getLoginStatus} from '../actions/loginAction'

const useLoginHandler = (username,password,submitted) => {
     const dispatch = useDispatch();
     const loginState = useSelector(state=> state.loginStatus)
     // it is better to put the dispatch inside a useEffect rather than outside
     useEffect(() => {
        if(!submitted) {return};
        dispatch(getLoginStatus(username,password))
     },[username,submitted]);


    if(loginState.loading) {
        console.log("please wait")
    }

    // .... rest of the logic
}

export default useLoginHandler

你对钩子的使用是错误的。它不应该在回调函数内。 它应该在最高级别。像下面这样的东西。此外,您不应该直接访问 dom 元素,而是使用 useRef 或 useState 来获取值

const Login = () => {
   const [username,setUsername] = useState('');
   const [password,setPassword] = useState('')
   const [submitted,setSubmitted] = useState(false);
   useLoginHandler(username,submitted); //custom hook should be used at this level
   return (
      <form onSubmit={(e) => setSubmitted(true)}>
      <input id="username" type="email" placeholder="Username" required onChange={e => setUsername(e.target.value)}/>
          </form>   
   )
}
,

您在此实现中使用了 2 个钩子 useDispatch & useSelector 并在函数内调用它们,这是无效用法。钩子只能在功能组件内调用。因此,将您的上述实现更改如下应该可以工作:

Login.js

import {useDispatch,useSelector} from 'react-redux'
import {getLoginStatus} from '../actions/loginAction'

const Login = () => {
  
  const dispatch = useDispatch()
  const loginState = useSelector(state=> state.loginStatus) 

  function userLogin(event) {
    event.preventDefault()
    const username = document.getElementById("username").value
    const password = document.getElementById("password").value
  
    dispatch(getLoginStatus(username,password))
  }


  return (
    <div className="flex-row align-items-center">
                  <form onSubmit={(e) => userLogin(e)}>
                    <h1>Login</h1>
                    
                      <input id="username" type="email" placeholder="Username" required/>
                 
                      <input id="password" type="password" placeholder="Password" required/>
      
                        <button type="submit" className="px-4">{loginState.loading ? "Please wait..." : "Login"}</button>
                </form>
    </div>
  )
}

export default Login

注意事项:

  • 直接在功能组件中而不是在功能组件的函数内部调用 useDispatch。然后我们可以在函数内部使用 useDispatch 的结果
  • 在功能组件中调用 useSelector,然后使用输出显示加载以代替按钮中的文本

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?