事件处理程序抛出无效的钩子调用错误
Event handler throws invalid hook call error
我正在学习 React 并尝试在子组件中实现一个简单的 onClick 按钮,结果却收到“无效挂钩调用”。为了找出问题所在,我删除了很多程序。
父组件:
import React, { useState } from "react";
import Menubar from '../Menubar/Menubar'
function SortingVisualizer() {
const [arr, setArr] = useState([]);
function newArray() {
const tempArr = [];
for(let i = 0; i < 100; i++) {
tempArr.push(Math.floor(Math.random() * 100) + 5)
}
setArr(tempArr);
}
return (
<div id="main-container">
<Menubar
data={arr}
/>
</div>
)
}
export default SortingVisualizer;
另一个模块中的子组件:
import React from "react";
import newArray from '../SortingVisualizer/SortingVisualizer'
import bubbleSort from '../algorithms/bubbleSort'
function Menubar(props) {
return(
<div id="menubar-container">
<button id="new-array-button" onClick={() => newArray()}>New Array</button> // Invalid hook error
<button id="bubble-sort-button" onClick={() => bubbleSort(props.data)}>Bubble Sort</button> // Works fine
</div>
)
}
export default Menubar;
当我 运行“npm ls react-dom”时,我只返回了一个版本,这应该意味着我没有版本不匹配的问题:
`-- react-dom@17.0.2
我怀疑我违反了一些钩子规则但不确定是哪一个。如果非要我猜的话,根据我看到的另一个问题,我认为这与 hooks 只能在顶层使用这一事实有关。我认为我的 newArray 的 onClick 以某种方式滥用了该钩子规则。
但是我不明白的是……难道“import newArray……”就足以使用另一个模块中的函数了吗?这不是它在普通 javascript 中的工作方式,其中一个模块可以简单地通过 importing/exporting 使用另一个模块的功能吗?
要将函数传递给子组件,可以将其作为props传递
<Menubar
data={arr}
newArray={newArray}
/>
然后在子组件中,调用 props 中的函数
const { newArray } = props;
return (
<div id="menubar-container">
<button id="new-array-button" onClick={newArray}>New Array</button>
您不能导入这样的函数。您必须将函数传递给子组件。
在父组件中
// SortingVisualizer.js
export const SortingVisualizer = () => {
const [arr, setArr] = useState([]);
const newArray = () => {
// ...
}
return (
<div id="main-container">
<Menubar data={arr} newArray={newArray} />
</div>
)
}
在子组件中
// import newArray from '../SortingVisualizer/SortingVisualizer'; Remove that line
import bubbleSort from '../algorithms/bubbleSort'
const Menubar = ({ newArray }) => {
return(
<div id="menubar-container">
<button id="new-array-button" onClick={() => newArray()}>New Array</button>
<button id="bubble-sort-button" onClick={() => bubbleSort(props.data)}>Bubble Sort</button> // Works fine
</div>
)
}
我不确定这是否是最佳解决方案,但您也可以创建一个挂钩
// useArray.js
import {useState} from "react"
const useArray = () => {
const [arr,setArray] = useState([])
function newArray() {
const tempArr = [];
for(let i = 0; i < 100; i++) {
tempArr.push(Math.floor(Math.random() * 100) + 5)
}
setArr(tempArr);
}
return {
newArray,
arr
}
}
export default useArray
即使在你的例子中我不明白为什么不把你的状态放在你的 child 组件中因为你的 parent 没有使用它
//Child component
import React from "react";
import bubbleSort from '../algorithms/bubbleSort'
function Menubar() {
const [arr, setArr] = useState([]);
const newArray = () => {
// ...
}
return(
<div id="menubar-container">
<button id="new-array-button" onClick={newArray}>New Array</button>
<button id="bubble-sort-button" onClick={() => bubbleSort(arr)}>Bubble Sort</button>
</div>
)
}
export default Menubar;
我正在学习 React 并尝试在子组件中实现一个简单的 onClick 按钮,结果却收到“无效挂钩调用”。为了找出问题所在,我删除了很多程序。
父组件:
import React, { useState } from "react";
import Menubar from '../Menubar/Menubar'
function SortingVisualizer() {
const [arr, setArr] = useState([]);
function newArray() {
const tempArr = [];
for(let i = 0; i < 100; i++) {
tempArr.push(Math.floor(Math.random() * 100) + 5)
}
setArr(tempArr);
}
return (
<div id="main-container">
<Menubar
data={arr}
/>
</div>
)
}
export default SortingVisualizer;
另一个模块中的子组件:
import React from "react";
import newArray from '../SortingVisualizer/SortingVisualizer'
import bubbleSort from '../algorithms/bubbleSort'
function Menubar(props) {
return(
<div id="menubar-container">
<button id="new-array-button" onClick={() => newArray()}>New Array</button> // Invalid hook error
<button id="bubble-sort-button" onClick={() => bubbleSort(props.data)}>Bubble Sort</button> // Works fine
</div>
)
}
export default Menubar;
当我 运行“npm ls react-dom”时,我只返回了一个版本,这应该意味着我没有版本不匹配的问题:
`-- react-dom@17.0.2
我怀疑我违反了一些钩子规则但不确定是哪一个。如果非要我猜的话,根据我看到的另一个问题,我认为这与 hooks 只能在顶层使用这一事实有关。我认为我的 newArray 的 onClick 以某种方式滥用了该钩子规则。
但是我不明白的是……难道“import newArray……”就足以使用另一个模块中的函数了吗?这不是它在普通 javascript 中的工作方式,其中一个模块可以简单地通过 importing/exporting 使用另一个模块的功能吗?
要将函数传递给子组件,可以将其作为props传递
<Menubar
data={arr}
newArray={newArray}
/>
然后在子组件中,调用 props 中的函数
const { newArray } = props;
return (
<div id="menubar-container">
<button id="new-array-button" onClick={newArray}>New Array</button>
您不能导入这样的函数。您必须将函数传递给子组件。
在父组件中
// SortingVisualizer.js
export const SortingVisualizer = () => {
const [arr, setArr] = useState([]);
const newArray = () => {
// ...
}
return (
<div id="main-container">
<Menubar data={arr} newArray={newArray} />
</div>
)
}
在子组件中
// import newArray from '../SortingVisualizer/SortingVisualizer'; Remove that line
import bubbleSort from '../algorithms/bubbleSort'
const Menubar = ({ newArray }) => {
return(
<div id="menubar-container">
<button id="new-array-button" onClick={() => newArray()}>New Array</button>
<button id="bubble-sort-button" onClick={() => bubbleSort(props.data)}>Bubble Sort</button> // Works fine
</div>
)
}
我不确定这是否是最佳解决方案,但您也可以创建一个挂钩
// useArray.js
import {useState} from "react"
const useArray = () => {
const [arr,setArray] = useState([])
function newArray() {
const tempArr = [];
for(let i = 0; i < 100; i++) {
tempArr.push(Math.floor(Math.random() * 100) + 5)
}
setArr(tempArr);
}
return {
newArray,
arr
}
}
export default useArray
即使在你的例子中我不明白为什么不把你的状态放在你的 child 组件中因为你的 parent 没有使用它
//Child component
import React from "react";
import bubbleSort from '../algorithms/bubbleSort'
function Menubar() {
const [arr, setArr] = useState([]);
const newArray = () => {
// ...
}
return(
<div id="menubar-container">
<button id="new-array-button" onClick={newArray}>New Array</button>
<button id="bubble-sort-button" onClick={() => bubbleSort(arr)}>Bubble Sort</button>
</div>
)
}
export default Menubar;