错误解决:未捕获的错误:无效的钩子调用。Hooks只能在函数组件的主体内部调用

错误消息

未捕获的错误:调用了无效的钩子。钩子只能在函数组件的主体内部调用。这可能发生的原因有以下几个可能。

    1. 可能您的React和渲染器(例如React DOM)版本不匹配

 

    1. 可能您正在违反Hooks规则

 

    可能您在同一个应用程序中有多个React的副本

翻译错误:无效的钩子调用。钩子只能在函数组件的主体内部调用。这可能是因为以下原因之一造成的:

    1. React和渲染器(例如React DOM)的版本可能不匹配。

 

    1. 可能违反了Hook规则。

 

    同一应用程序可能存在多个React副本。

我预计

    1. React和渲染器(如React DOM)的版本不匹配。

 

    1. →没有在其他地方出现错误,可能性很低。

 

    1. 可能违反了Hook规则。

 

    1. →可能性存在。

 

    1. 同一应用可能存在多个React副本。

 

    →不存在。

从这些中看来,你是在错误地使用 hooks?

代码 (Mandarin Chinese: ” mǎ”)

下面是可能与之相关的代码。

/**
 * TodoTemplate
 *
 * @package components
 */
import { useTodoContext } from '../../../contexts/TodoContext';
import { InputForm } from '../../atoms/InputForm';
import { TextAreaForm } from '../../atoms/TextAreaForm';
import { CommonButton } from '../../atoms/CommonButton';
import { useTodoCreateTemplate } from './useTodoCreateTemplate';
import styles from './styles.module.css';

export const TodoCreateTemplate = () => {
  const { addTodo } = useTodoContext();
  const [
    { inputTitle, inputContent },
    { handleChangeTitle, handleChangeContent, handleCreateTodo },
  ] = useTodoCreateTemplate({ addTodo });

  /**
   * TodoTemplate
   * @returns {JSX.Element}
   * @constructor
   */
  return (
    <div className={styles.container}>
      <div className={styles.titleBox}>
        <h2>Create Todo</h2>
      </div>

      <form onSubmit={handleCreateTodo}>
        <InputForm inputVal={inputTitle} placeholder={'Title'} onChange={handleChangeTitle} />

        <TextAreaForm
          inputVal={inputContent}
          placeholder={'Content'}
          onChange={handleChangeContent}
        />

        <CommonButton label={'Create Todo'} type={'submit'} />
      </form>
    </div>
  );
};
/**
 * useTodoCreateTemplate
 *
 * @package hooks
 */
import { useState, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { TODO_PATH } from '../../../constants/pagenations';

~~~

  /**
   * Todo の新規登録処理
   * @type {function(*): void |*}
   */
  const handleCreateTodo = useCallback(
    () => {
      if (inputTitle && inputContent) {
        addTodo(inputTitle, inputContent);
        useNavigate(TODO_PATH.TOP);
      }
    },
    // これらが更新された時のみ、関数を再生成する
    [addTodo, inputTitle, inputContent, navigate],
  );
  
~~~
};
import { useState, useMemo, useCallback } from 'react';
import { INIT_TODO_LIST } from '../constants/data';

~~~

export const useTodo = () => {

~~~

  /**
   * Todo 新規登録処理
   * @param {*} e
   */
  const addTodo = useCallback((title, content) => {
    const newId = originTodoList.length + 1;
    const newTodo = {
      id: newId,
      title: title,
      content: content,
    };
    setOriginTodoList([...originTodoList, newTodo]);
    console.log(originTodoList);
  });
  
~~~
};

嘗試過的事情

    • hooks/useTodo.js の処理をコメントアウトしてもエラー解消しない。

 

    TodoCreateTemplate/index.jsx はインポートして使用しているだけなので、原因である可能性は低いか。

→ 是因为TodoCreateTemplate/useTodoCreateTemplate.js导致的吗?

在这个网页中,我有一种感觉,即规则1:钩子只能在顶层调用。

解决

只需要一种选择,原因是:

原因是由于

/**
 * useTodoCreateTemplate
 *
 * @package hooks
 */
import { useState, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { TODO_PATH } from '../../../constants/pagenations';

~~~

  /**
   * Todo の新規登録処理
   * @type {function(*): void |*}
   */
  const handleCreateTodo = useCallback(
    () => {
      if (inputTitle && inputContent) {
        addTodo(inputTitle, inputContent);
        useNavigate(TODO_PATH.TOP);
      }
    },
    // これらが更新された時のみ、関数を再生成する
    [addTodo, inputTitle, inputContent, navigate],
  );
  
~~~
};

使用导航功能前往TODO_PATH.TOP。

  const handleCreateTodo = useCallback(
    () => {
      if (inputTitle && inputContent) {
        addTodo(inputTitle, inputContent);
        useNavigate(TODO_PATH.TOP);
        これ
      }
    },
};
  const navigate = useNavigate();
  
  const handleCreateTodo = useCallback(
    () => {
      if (inputTitle && inputContent) {
        addTodo(inputTitle, inputContent);
        navigate(TODO_PATH.TOP);
      }
    },
};

只需要一种选择,并通过采取这种方法来解决。是否取决于礼仪呢…?

广告
将在 10 秒后关闭
bannerAds