无效的挂接调用。挂钩只能在功能组件的主体内部调用

时间:2019-06-19 08:57:15

标签: reactjs material-ui

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

  

无效的挂钩调用。钩子只能在   功能组件。可能发生以下情况之一   原因:   1.您的React和渲染器版本可能不匹配(例如React DOM)   2.您可能违反了《钩子规则》   3.您可能在同一应用程序中拥有多个React副本。有关如何调试和调试的提示,请参见   解决此问题。

shared-component.module.ts

24 个答案:

答案 0 :(得分:9)

您可以通过调用Arrow函数来使用“导出默认值”,该函数通过将其传递给MaterialUI类对象props来返回其React.Component,而后者又将在Component render()中使用。

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

export default () => {
    const classes = useStyles();
    return (
        <AllowanceClass classes={classes} />
    )
}

答案 1 :(得分:6)

当我使用npm link安装使用cra构建的本地库时遇到了这个问题。我找到了答案here。从字面上说:

This problem can also come up when you use npm link or an equivalent. 
In that case, your bundler might “see” two Reacts — one in application folder
and one in your library folder. Assuming 'myapp' and 'mylib' are sibling folders,
one possible fix is to run 'npm link ../myapp/node_modules/react' from 'mylib'.
This should make the library use the application’s React copy.

因此,从我的项目文件夹中运行命令:npm link ../../libraries/core/decipher/node_modules/react已解决了该问题。

答案 2 :(得分:3)

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

答案 3 :(得分:2)

使您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;

答案 4 :(得分:2)

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

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

答案 5 :(得分:1)

React linter假定每个以use开头的方法,因为钩子和钩子在类内部不起作用。将const useStyles重命名为其他不以use开头的东西,例如const myStyles,就可以了。

更新

makeStyles是hook API,您不能在类内部使用它。您可以使用样式化的组件API。参见here

答案 6 :(得分:1)

我刚刚开始使用钩子,并且在函数内调用 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]);

希望对某人有帮助!

答案 7 :(得分:0)

就我而言,我在 package-json 中所做的更改会导致问题。

npm install react-redux

解决这个问题

答案 8 :(得分:0)

就我而言,我从两个项目中删除了 package-lock.jsonnode_modules,然后重新安装,现在工作正常。


// project structure


root project
- package-lock.json
- package.json // all dependencies are installed here
- node_modules

-- second project
-- package-lock.json
-- package.json 
  "dependencies": {
    "react": "file:../node_modules/react",
    "react-dom": "file:../node_modules/react-dom",
    "react-scripts": "file:../node_modules/react-scripts"
  },
-- node_modules


首先不确定是什么导致了这个问题,因为我以前也遇到过这种情况,并且执行了与上述相同的步骤,问题得到了解决。

答案 9 :(得分:0)

就我而言,我在 FlatListrenderItem 属性中传递组件名称而不是函数。因为我的组件是一个功能组件,所以它可以更早地工作,但是当我在其中添加钩子时,它失败了。

之前:

    <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>
        }
      />

之后:

    <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>
        }
      />

答案 10 :(得分:0)

这是为我解决的问题。我有文件夹 node_modules 和文件 package.json 和 package-lock.json 在我的组件文件夹以及它所属的项目的根目录中。我从不属于它们的地方删除了它们。不要问我做了什么把它们放在那里,我一定是在错误的位置做了一个 npm 的东西。

答案 11 :(得分:0)

将此添加到您的 package.json

"peerDependencies": {
   "react": ">=16.8.0",
   "react-dom": ">=16.8.0"
}

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

答案 12 :(得分:0)

如果您使用 mobx,并且您的功能组件包装在 mobx observer 函数中,也会发生此错误。如果是这种情况,请确保您使用的是 mobx-react 版本 6.0.0 或更高版本。旧版本会将您的功能组件转换为隐藏的类,并且所有钩子都将因此错误而失败。

在此处查看答案:React Hooks Mobx: invalid hook call. Hooks can only be called inside of the body of a function component

答案 13 :(得分:0)

我的共享库之间不同版本的反应似乎是问题(16 和 17),都改为 16。

答案 14 :(得分:0)

当您使用依赖项而不安装它时也会发生。 当我从 '@material-ui/icons/' 调用 MenuIcon 时发生在我身上,但它在项目中丢失了。

答案 15 :(得分:0)

complementing the following comment

对于使用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);

答案 16 :(得分:0)

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

答案 17 :(得分:0)

就我而言,我试图在Windows上使用mdbreact。虽然安装了,但是我遇到了以上错误。我必须重新安装它,一切正常。蚂蚁图书馆两次发生在我身上

答案 18 :(得分:0)

发现此错误:找到了解决方法。

由于某种原因,我的标签上有2个onClick属性。 使用您或某人的自定义组件时要小心,也许其中一些已经具有onClick属性。

答案 19 :(得分:0)

如果以上所有方法都不起作用,特别是如果具有较大的大小依赖性(如我的情况),则构建和加载都至少花费15秒,因此延迟似乎发出了一条错误消息“ Invalid hook call。 ” 因此,您可以做的是花一些时间来确保在测试之前完成构建。

答案 20 :(得分:0)

您可以将类组件转换为钩子,但是Material v4具有withStyles HOC。 https://material-ui.com/styles/basics/#higher-order-component-api 使用此HOC,您可以保持代码不变。

答案 21 :(得分:-1)

我的情况。... HOOKS中的 解决方案

const [cep, setCep] = useState('');
const mounted = useRef(false);

useEffect(() => {
    if (mounted.current) {
        fetchAPI();
      } else {
        mounted.current = true;
      }
}, [cep]);

const setParams = (_cep) => {
    if (cep !== _cep || cep === '') {
        setCep(_cep);
    }
};

答案 22 :(得分:-1)

致任何可能正在寻找此问题的快速解决方案的人:

你可能违反了钩子规则。 要解决此问题,请移动 :

?const [x, setX] = useState(0);

到调用它的函数的 TOP-LEVEL 而不是在函数之外。

function App() {
   ?const [t, setTime] = useState("");

   return (
      <div>
         <h1>{x}</h1>
         <button onClick={() => setTime(x+1)}>Get Time</button>
      </div>
 );
}

? https://reactjs.org/warnings/invalid-hook-call-warning.html

答案 23 :(得分:-1)

我遇到了这个问题,我的错误原因是我开发了项目A并且我将另一个项目B链接到了A,但是A有React包,B也有React包,它们是相同的版本(16.13)。 但这导致了问题,我设置文件的意思是 webpack.config.js,如下所示:

alias: {
  'react': path.join(path.resolve(__dirname), '../node_modules/react'),
},

set B React package 解析为A React package,我猜原因是一个项目不能有两个或多个React包,即使它们是相同的版本。但我无法验证我的猜测。