Javascript 如何从函数或事件内部的react钩子设置数据?

Javascript 如何从函数或事件内部的react钩子设置数据?,javascript,reactjs,next.js,Javascript,Reactjs,Next.js,我正在尝试创建钩子,这样我就可以重用我必须在不同组件中更改的数据 我正在使用并且需要使用useTab,一个用于更改选项卡id的自定义挂钩 import React, { useContext } from 'react'; import { ProductsContext } from './ProductsContext'; import AppBar from '@material-ui/core/AppBar'; import Tabs from '@material-ui/core/Ta

我正在尝试创建钩子,这样我就可以重用我必须在不同组件中更改的数据

我正在使用并且需要使用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;
我当然会遇到一个错误,我不能在函数内部使用钩子,但我不知道还有什么其他方法可以做到这一点


如何从useTabs更改tabValue

错误可能在这里:

const handleTabChange = (e, newTabValue) => {
    useTab(newTabValue);
}
您违反了一个主要规则:

不要在循环、条件或嵌套函数中调用钩子。 相反,总是在React函数的顶层使用钩子

这个规则的原因有点复杂,但基本上可以归结为这样一个想法:钩子应该只在React函数组件的顶层调用,因为必须保证钩子在每次运行组件函数时都能运行

因此,为什么会出现错误“我不能在函数内部使用钩子”

无论如何,现在还不清楚为什么要在这里使用带有
useffect()
的自定义钩子。这似乎完全没有必要-导航组件内部的常规
useffect()

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>
    ); 
};
const ProductsNav=()=>{
const{products,categories,loading}=useContext(ProductsContext);
常量[tabValue,setTabValue]=useState(0);
常量handleTabChange=(e,newTabValue)=>{
设置值(newTabValue);
}
返回(
{
Array.from(categories).map(categority=>(
!category.unlisted&&()
))
}
); 
};

错误可能在这里:

const handleTabChange = (e, newTabValue) => {
    useTab(newTabValue);
}
您违反了一个主要规则:

不要在循环、条件或嵌套函数中调用钩子。 相反,总是在React函数的顶层使用钩子

这个规则的原因有点复杂,但基本上可以归结为这样一个想法:钩子应该只在React函数组件的顶层调用,因为必须保证钩子在每次运行组件函数时都能运行

因此,为什么会出现错误“我不能在函数内部使用钩子”

无论如何,现在还不清楚为什么要在这里使用带有
useffect()
的自定义钩子。这似乎完全没有必要-导航组件内部的常规
useffect()

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>
    ); 
};
const ProductsNav=()=>{
const{products,categories,loading}=useContext(ProductsContext);
常量[tabValue,setTabValue]=useState(0);
常量handleTabChange=(e,newTabValue)=>{
设置值(newTabValue);
}
返回(
{
Array.from(categories).map(categority=>(
!category.unlisted&&()
))
}
); 
};

Hi我正在使用一个自定义钩子,这样我可以在另一个组件中使用TabPane…@kinx在这种情况下,您只需将
tabValue
状态在组件层次结构中向上移动几个级别,这样您就可以将它提供给多个组件(作为道具传递)。这个概念被称为“提升状态”,理解它对于您如何管理React应用程序中的状态至关重要。这与钩子无关。嗨,我正在使用一个自定义钩子,这样我可以在另一个组件中使用TabPane…@kinx在这种情况下,您只需将
tabValue
状态在组件层次结构中向上移动几个级别,这样您就可以将其作为道具传递给多个组件。这个概念被称为“提升状态”,理解它对于您如何管理React应用程序中的状态至关重要。这与钩子无关。