开发者问题收集

尝试实现 useEffect 时发生奇怪的错误

2019-04-26
5263

我试图在返回几个元素的 cockpit 函数中使用 useEffect,但我收到这个奇怪的错误,提示“第 6 行:React Hook“useEffect”在函数“cockpit”中被调用,它既不是 React 函数组件也不是自定义 React Hook 函数 react-hooks/rules-of-hooks”。

但我的 cockpit 组件肯定是一个函数吧?

import React, { useEffect } from 'react'

import classes from './Cockpit.css'

const cockpit = (props) => {
  useEffect(() => {
    console.log('I work!')
  })

  const assignedClasses = []
  let btnClass = ''
  if (props.showPersons) {
    btnClass = classes.Red;
  }

  if (props.persons.length <= 2) {
    assignedClasses.push(classes.red)
  }
  if (props.persons.length <= 1) {
    assignedClasses.push(classes.bold)
  }

  return (
    <div className={classes.Cockpit}>
      <h1>{props.title}</h1>
      <p className={assignedClasses.join(' ')}>HELLO, HELLO!</p>
      <button
        className={btnClass}
        onClick={props.clicked}>Click me!</button>
    </div>
  )
}


export default cockpit
3个回答

仅供参考,组件名称应以大写字母开头

Zohaib Ijaz
2019-04-26

根据 react 文档 用户定义组件必须大写

如果您只使用 react,那么您可以定义以小写字母开头的组件函数名称,但是您是否注意到,当您在渲染中使用组件时,您将其用作 import Cockpit from './bla bla' 。 因此,如果您确实有一个以小写字母开头的组件,请在 JSX 中使用它之前将其分配给大写变量。

但是如果您在该组件中使用带有 react 的 hook,那么您的组件必须大写。 我也看过 Udemy 课程。那个人对名为 cocktail 的组件没意见,但我认为这与 react 和 hook 的版本有关!

我再次注意到您正在使用 css 模块。您是否设置了使用 css 模块作为课程的配置?? 我必须提到,您无需运行“npm run jet”即可使用 css 模块,并且这些复杂的配置由于 React 2 支持 css 模块,您只需要将扩展​​名从 .css 更改为 .module.css

这是您的干净代码:

import React, { useEffect } from 'react'

import classes from './Cockpit.module.css'

const Cockpit = (props) => {
  useEffect(() => {
    console.log('I work!')
  })

  const assignedClasses = []
  let btnClass = ''
  if (props.showPersons) {
    btnClass = classes.Red;
  }

  if (props.persons.length <= 2) {
    assignedClasses.push(classes.red)
  }
  if (props.persons.length <= 1) {
    assignedClasses.push(classes.bold)
  }

  return (
    <div className={classes.Cockpit}>
      <h1>{props.title}</h1>
      <p className={assignedClasses.join(' ')}>HELLO, HELLO!</p>
      <button
        className={btnClass}
        onClick={props.clicked}>Click me!</button>
    </div>
  )
}


export default Cockpit
Mehedi Hasan Shifat
2020-06-20
//This is the exact solution

import React, { useEffect } from 'react';

import classes from './Cockpit.css';

const Cockpit = props => {
  useEffect(() => {
    console.log('[Cockpit.js] useEffect');
    // Http request...
    setTimeout(() => {
      alert('Saved data to cloud!');
    }, 1000);
    return () => {
      console.log('[Cockpit.js] cleanup work in useEffect');
    };
  }, []);

  useEffect(() => {
    console.log('[Cockpit.js] 2nd useEffect');
    return () => {
      console.log('[Cockpit.js] cleanup work in 2nd useEffect');
    };
  });

  // useEffect();

  const assignedClasses = [];
  let btnClass = '';
  if (props.showPersons) {
    btnClass = classes.Red;
  }

  if (props.persons.length <= 2) {
    assignedClasses.push(classes.red); // classes = ['red']
  }
  if (props.persons.length <= 1) {
    assignedClasses.push(classes.bold); // classes = ['red', 'bold']
  }

  return (
    <div className={classes.Cockpit}>
      <h1>{props.title}</h1>
      <p className={assignedClasses.join(' ')}>This is really working!</p>
      <button className={btnClass} onClick={props.clicked}>
        Toggle Persons
      </button>
    </div>
  );
};

export default Cockpit;

// Look out for the identifier names of the const and the export
Shivam Lakhwara
2019-07-23