无效的钩子调用。Hooks 只能在函数组件内部调用

lwi*_*win 130 reactjs material-ui react-hooks

我是 React 的新手,现在我想在表中显示一些记录,现在我收到了这个错误。请帮帮我。

无效的钩子调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一而发生的: 1. 你可能有不匹配的 React 版本和渲染器(例如 React DOM) 2. 你可能违反了 Hooks 规则 3. 你可能有多个 React 副本有关如何调试和解决此问题的提示,请参阅相同的应用程序。

import React,{Component} from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Paper from '@material-ui/core/Paper';

const useStyles = makeStyles(theme => ({
    root: {
      width: '100%',
      marginTop: theme.spacing(3),
      overflowX: 'auto',
    },
    table: {
      minWidth: 650,
    },
  }));

class allowance extends Component{
    constructor(){
        super();
        this.state={
            allowances:[],
        };

    }

    componentWillMount() {
        fetch('http://127.0.0.1:8000/allowances')
        .then(data=>{  

            return data.json();      

        }).then(data=> {          

            this.setState({allowances : data});

            console.log("allowance state",this.state.allowances);
        })

    }



    render() {
        const classes = useStyles();
        return (
            <Paper className={classes.root}>
              <Table className={classes.table}>
                <TableHead>
                  <TableRow>
                    <TableCell>Allow ID</TableCell>
                    <TableCell align="right">Description</TableCell>
                    <TableCell align="right">Allow Amount</TableCell>
                    <TableCell align="right">AllowType</TableCell>

                  </TableRow>
                </TableHead>
                <TableBody>
                  {this.state.allowances.map(row => (
                    <TableRow key={row.id}>
                      <TableCell component="th" scope="row">
                        {row.AllowID}
                      </TableCell>
                      <TableCell align="right">{row.AllowDesc}</TableCell>
                      <TableCell align="right">{row.AllowAmt}</TableCell>
                      <TableCell align="right">{row.AllowType}</TableCell>                    
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </Paper>
          );}

}

export default allowance;
Run Code Online (Sandbox Code Playgroud)

Gia*_* Le 61

因为你Only Call Hooks from React Functions。在此处查看更多信息https://reactjs.org/docs/hooks-rules.html#only-call-hooks-from-react-functions。只需将Allowance类组件转换为功能组件。在这里工作的演示https://codesandbox.io/s/amazing-poitras-k2fuf

const Allowance = () => {
  const [allowances, setAllowances] = useState([]);

  useEffect(() => {
    fetch("http://127.0.0.1:8000/allowances")
      .then(data => {
        return data.json();
      })
      .then(data => {
        setAllowances(data);
      })
      .catch(err => {
        console.log(123123);
      });
  }, []);

  const classes = useStyles();
  return (
    <Paper className={classes.root}>
      <Table className={classes.table}>
        <TableHead>
          <TableRow>
            <TableCell>Allow ID</TableCell>
            <TableCell align="right">Description</TableCell>
            <TableCell align="right">Allow Amount</TableCell>
            <TableCell align="right">AllowType</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {allowances.map(row => (
            <TableRow key={row.id}>
              <TableCell component="th" scope="row">
                {row.AllowID}
              </TableCell>
              <TableCell align="right">{row.AllowDesc}</TableCell>
              <TableCell align="right">{row.AllowAmt}</TableCell>
              <TableCell align="right">{row.AllowType}</TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </Paper>
  );
};

export default Allowance;
Run Code Online (Sandbox Code Playgroud)

  • 有件事想问你,调用setAllowances(data)后,津贴应该有数据吧?不然什么时候津贴有数据? (2认同)

the*_*gie 48

我以前npm link安装本地库时遇到了这个问题,我使用cra. 我在这里找到了答案。字面意思是:

当您使用 npm link 或等效物时,也会出现此问题。在这种情况下,你的打包器可能会“看到”两个 Reacts——一个在应用程序文件夹中,一个在你的库文件夹中。假设“myapp”和“mylib”是同级文件夹,一种可能的解决方法是从“mylib”运行“npm link ../myapp/node_modules/react”。这应该使库使用应用程序的 React 副本。

因此,运行命令:npm link <path_to_local_library>/node_modules/react,例如。在我的情况下npm link ../../libraries/core/decipher/node_modules/react,项目目录中的问题已解决。

  • 谢了哥们!你救了我的命!所有通过 npm/yarn 链接使用本地包的人,请遵循此操作! (6认同)
  • 尝试“npm ls react”,它会列出所有 React 版本,并确保删除所有重复的 React 版本或链接到特定版本。 (5认同)
  • 我花了 8 个小时来解决这个问题,并尝试以不同的方式完成该功能。太感谢了 (3认同)
  • 这对我有用。这正是我的问题。 (2认同)
  • 那么在npm上发布的时候会报错吧?或者也许不是,因为它是链接的,在我的机器上它将使用链接中的反应,并且在发布后,它将使用它自己的。 (2认同)
  • 要完成这个答案,请检查反应存储库中有关此问题的链接 https://github.com/facebook/react/issues/14257#issuecomment-809702813 (2认同)

小智 25

对我来说,错误是在默认导出的函数之外调用函数 useState


lui*_*sta 17

您可以通过调用返回其 React.Component 的箭头函数来使用“导出默认值”,方法是将它传递给 MaterialUI 类对象 props,而 props 又将在 Component render () 中使用。

class AllowanceClass extends Component{
    ...
    render() {
        const classes = this.props.classes;
        ...
    }
}

export default () => {
    const classes = useStyles();
    return (
        <AllowanceClass classes={classes} />
    )
}
Run Code Online (Sandbox Code Playgroud)


小智 13

昨天,我缩短了代码(刚刚添加<Provider store={store}>),但仍然遇到了这个无效的钩子调用问题。这让我突然意识到自己犯了什么错误:我没有在那个文件夹中安装react-redux软件。

我已经在另一个项目文件夹中安装了这个软件,所以我没有意识到这个也需要它。安装后,错误消失。


小智 12

将其添加到您的 package.json 中

"peerDependencies": {
   "react": ">=16.8.0",
   "react-dom": ">=16.8.0"
}
Run Code Online (Sandbox Code Playgroud)

来源:https://robkendal.co.uk/blog/2019-12-22-solving-react-hooks-invalid-hook-call-warning


小智 10

当您以错误的方式从react-redux声明useDispatch时,也可能会发生此错误:当您使用:
const dispatch = useDispatch而不是:时
const dispatch = useDispatch();(即记住添加括号)


Sin*_*ina 9

React linter 假设每个方法都以use钩子开头,而钩子在类中不起作用。通过重命名const useStyles成别的不开始与useconst myStyles你是好去。

更新:

makeStyles是 hook api,您不能在类中使用它。您可以使用样式化组件 API。看这里

  • 将 usestyles 更改为 mystyles 但仍然发生错误。 (2认同)
  • 是否有任何文件表明这是真的? (2认同)

Shi*_*rma 8

FlatList就我而言,我在s prop中传递组件名称renderItem而不是函数。它早些时候可以工作,因为我的组件是一个功能组件,但是当我在其中添加钩子时,它失败了。

前:

    <FlatList
        data={memberList}
        renderItem={<MemberItem/>}
        keyExtractor={member => member.name.split(' ').join('')}
        ListEmptyComponent={
          <Text style={{textAlign: 'center', padding: 30}}>
            No Data: Click above button to fetch data
          </Text>
        }
      />
Run Code Online (Sandbox Code Playgroud)

后:

    <FlatList
        data={memberList}
        renderItem={({item, index}) => <MemberItem item={item} key={index} />}
        keyExtractor={member => member.name.split(' ').join('')}
        ListEmptyComponent={
          <Text style={{textAlign: 'center', padding: 30}}>
            No Data: Click above button to fetch data
          </Text>
        }
      />
Run Code Online (Sandbox Code Playgroud)


JxD*_*gel 6

补充以下评论

对于那些使用 redux 的人:

class AllowanceClass extends Component{
    ...
    render() {
        const classes = this.props.classes;
        ...
    }
}
    
const COMAllowanceClass = (props) =>
{
    const classes = useStyles();
    return (<AllowanceClass classes={classes} {...props} />);
};

const mapStateToProps = ({ InfoReducer }) => ({
    token: InfoReducer.token,
    user: InfoReducer.user,
    error: InfoReducer.error
});
export default connect(mapStateToProps, { actions })(COMAllowanceClass);
Run Code Online (Sandbox Code Playgroud)


Gab*_*son 6

我的共享库之间不同版本的 React 似乎是问题所在(16 和 17),将两者都更改为 16。


ish*_*rya 5

我刚刚开始使用钩子,当我在函数内调用 useEffect时收到上述警告:

然后我必须将 useEffect 移到函数之外,如下所示:

 const onChangeRetypePassword = async value => {
  await setRePassword(value);
//previously useEffect was here

  };
//useEffect outside of func 

 useEffect(() => {
  if (password !== rePassword) {
  setPasswdMismatch(true);

     } 
  else{
    setPasswdMismatch(false);
 }
}, [rePassword]);
Run Code Online (Sandbox Code Playgroud)

希望它对某人有帮助!


归档时间:

查看次数:

290169 次

最近记录:

4 年,2 月 前