错误解决:未捕获的错误:无效的钩子调用。Hooks只能在函数组件的主体内部调用
错误消息
未捕获的错误:调用了无效的钩子。钩子只能在函数组件的主体内部调用。这可能发生的原因有以下几个可能。
-
- 可能您的React和渲染器(例如React DOM)版本不匹配
-
- 可能您正在违反Hooks规则
- 可能您在同一个应用程序中有多个React的副本
翻译错误:无效的钩子调用。钩子只能在函数组件的主体内部调用。这可能是因为以下原因之一造成的:
-
- React和渲染器(例如React DOM)的版本可能不匹配。
-
- 可能违反了Hook规则。
- 同一应用程序可能存在多个React副本。
我预计
-
- React和渲染器(如React DOM)的版本不匹配。
-
- →没有在其他地方出现错误,可能性很低。
-
- 可能违反了Hook规则。
-
- →可能性存在。
-
- 同一应用可能存在多个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);
}
},
};
只需要一种选择,并通过采取这种方法来解决。是否取决于礼仪呢…?