我正在尝试学习创建钩子,以便可以重复使用必须在不同组件中更改的数据。
我正在使用Material UI's Tabs,需要使用useTab,这是一个用于更改标签页ID的自定义钩子。
import React, { useContext } from 'react';
import { ProductsContext } from './ProductsContext';
import AppBar from '@material-ui/core/AppBar';
import Tabs from '@material-ui/core/Tabs';
import Tab from '@material-ui/core/Tab';
import { useTab } from '../../hooks/tab';
const ProductsNav = () => {
const {products, categories, loading} = useContext(ProductsContext);
const [tabValue] = useTab(0);
const handleTabChange = (e, newTabValue) => {
useTab(newTabValue);
}
return (
<div className="products">
<AppBar position="static">
<Tabs value={tabValue} onChange={ handleTabChange }>
{
Array.from(categories).map(category => (
!category.unlisted && (<Tab label={category.title} key={category.id}/>)
))
}
</Tabs>
</AppBar>
</div>
);
};
export default ProductsNav;
我知道它是通过文档中的子功能来完成此操作的,但我不仅尝试以自己的方式复制和粘贴并完成操作。
这是我自定义的useTab钩子:
import {useState, useEffect} from 'react';
export const useTab = (selectedTab) => {
const [tabValue, setTabValue] = useState(0);
useEffect(() => {
setTabValue(selectedTab);
}, []);
return [tabValue];
}
我当然遇到了错误,我不能在函数内部使用钩子,但是我很困惑其他方法。
如何从useTabs更改tabValue?
答案 0 :(得分:0)
错误可能在这里:
const handleTabChange = (e, newTabValue) => {
useTab(newTabValue);
}
您违反了主要的Rules of Hooks之一:
请勿在循环,条件或嵌套函数中调用Hook。 相反,请始终在React函数的顶层使用挂钩。
这个规则的原因有点复杂,但是从根本上可以归结为这样的想法:在React功能组件的顶层只能调用 ,因为必须保证 在每次运行组件功能时运行。
因此,为什么会出现错误“我不能在函数内部使用钩子” ...
无论如何,目前尚不清楚为什么在这里使用带有useEffect()
的自定义钩子。这似乎完全没有必要-导航组件内部的常规useEffect()
钩子已经足够了:
const ProductsNav = () => {
const {products, categories, loading} = useContext(ProductsContext);
const [tabValue, setTabValue] = useState(0);
const handleTabChange = (e, newTabValue) => {
setTabValue(newTabValue);
}
return (
<div className="products">
<AppBar position="static">
<Tabs value={tabValue} onChange={ handleTabChange }>
{
Array.from(categories).map(category => (
!category.unlisted && (<Tab label={category.title} key={category.id}/>)
))
}
</Tabs>
</AppBar>
</div>
);
};