ncaught Error: Invalid hook call. Hooks can only be called inside of the body

ncaught Error: Invalid hook call. Hooks can only be called inside of the body

你好,我是编码新手,我想使用 redux 来实现我的登录功能,但是我的代码有问题,正如它所说的那样

未捕获的错误:挂钩调用无效。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一造成的:

  1. 您的 React 和渲染器版本可能不匹配(例如 React DOM)
  2. 您可能违反了 Hooks 规则
  3. 您可能在同一个应用程序中拥有多个 React 副本 有关如何调试和修复此问题的提示,请参阅 https://reactjs.org/link/invalid-hook-call

这是我的代码

import React, { useEffect, useState } from 'react'
import { Button, Container, Form } from 'react-bootstrap'
import { useDispatch, useSelector } from 'react-redux'
import { Link, useLocation, useNavigate } from 'react-router-dom'
import { login } from '../actions/userAction'
import ErrorMessageBox from '../components/ErrorMessagebox'
import Loading from '../components/Loading'

export const SignInScreen = () => {
  const navigate = useNavigate
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')

  const { search } = useLocation()
  const redirectInUrl = new URLSearchParams(search).get('redirect')
  const redirect = redirectInUrl ? redirectInUrl : '/'

  const userLogin = useSelector((state) => state.userLogin)
  const { userInfo, loading, error } = userLogin
  const dispatch = useDispatch()

  useEffect(() => {
    if (userInfo) {
      navigate(redirect)
    }
  }, [navigate, userInfo, redirect])

  const submitHandler = (e) => {
    e.preventDefault()
    dispatch(login(email, password))
  }

  return (
    <Container className="small-container">
      <h1 className="my-3">Sign In</h1>
      {error && <ErrorMessageBox variant="danger">{error}</ErrorMessageBox>}
      {loading && <Loading />}
      <Form onSubmit={submitHandler}>
        <Form.Group className="mb-3" controlId="email">
          <Form.Label>Email</Form.Label>
          <Form.Control
            type="email"
            required
            onChange={(e) => setEmail(e.target.value)}
          />
        </Form.Group>
        <Form.Group className="mb-3" controlId="password">
          <Form.Label>Password</Form.Label>
          <Form.Control
            type="password"
            required
            onChange={(e) => setPassword(e.target.value)}
          />
        </Form.Group>
        <div className="mb-3">
          <Button type="submit">Sign In</Button>
        </div>
        <div className="mb-3">
          New Customer?{' '}
          <Link to={`/signup?redirect=${redirect}`}>Create new account</Link>
        </div>
      </Form>
    </Container>
  )
}

我有 运行 npm ls react-dom 它显示了

enter image description here

请帮忙,我不知道该怎么办

先生。我认为你打错了字,错误就是因为这个。 将 useNavigate 更改为 useNavigate()

import React, { useEffect, useState } from 'react'
import { Button, Container, Form } from 'react-bootstrap'
import { useDispatch, useSelector } from 'react-redux'
import { Link, useLocation, useNavigate } from 'react-router-dom'
import { login } from '../actions/userAction'
import ErrorMessageBox from '../components/ErrorMessagebox'
import Loading from '../components/Loading'

export const SignInScreen = () => {
  const navigate = useNavigate()
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')

  const { search } = useLocation()
  const redirectInUrl = new URLSearchParams(search).get('redirect')
  const redirect = redirectInUrl ? redirectInUrl : '/'

  const userLogin = useSelector((state) => state.userLogin)
  const { userInfo, loading, error } = userLogin
  const dispatch = useDispatch()

  useEffect(() => {
    if (userInfo) {
      navigate(redirect)
    }
  }, [navigate, userInfo, redirect])

  const submitHandler = (e) => {
    e.preventDefault()
    dispatch(login(email, password))
  }

  return (
    <Container className="small-container">
      <h1 className="my-3">Sign In</h1>
      {error && <ErrorMessageBox variant="danger">{error}</ErrorMessageBox>}
      {loading && <Loading />}
      <Form onSubmit={submitHandler}>
        <Form.Group className="mb-3" controlId="email">
          <Form.Label>Email</Form.Label>
          <Form.Control
            type="email"
            required
            onChange={(e) => setEmail(e.target.value)}
          />
        </Form.Group>
        <Form.Group className="mb-3" controlId="password">
          <Form.Label>Password</Form.Label>
          <Form.Control
            type="password"
            required
            onChange={(e) => setPassword(e.target.value)}
          />
        </Form.Group>
        <div className="mb-3">
          <Button type="submit">Sign In</Button>
        </div>
        <div className="mb-3">
          New Customer?{' '}
          <Link to={`/signup?redirect=${redirect}`}>Create new account</Link>
        </div>
      </Form>
    </Container>
  )
}