Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A weird error occurring when trying to implement useEffect

I am trying to use useEffect inside of my cockpit function that returns a couple of elements, but I get this weird error saying that "Line 6: React Hook "useEffect" is called in function "cockpit" which is neither a React function component or a custom React Hook function react-hooks/rules-of-hooks".

But surely my cockpit component is a function?

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
like image 945
Bi-HanNoobSaibot Avatar asked Apr 26 '19 20:04

Bi-HanNoobSaibot


3 Answers

Just for reference, Component name should start with Capital letter

like image 170
Zohaib Ijaz Avatar answered Oct 12 '22 12:10

Zohaib Ijaz


According to react doc User-Defined Components Must Be Capitalized !

In case if you are using only react then you can define your component function name starting with small letter but have you noticed that when you are using the component in rendering you are using it as import Cockpit from './bla bla' . So If you do have a component that starts with a lowercase letter, assign it to a capitalized variable before using it in JSX.

But if you are using hook with react in that component then your Components have to be capitalized. I have also seen the Udemy course . That guy was okey with cocktail named component but i think it was related to the version of react and hook !

Again i have noticed that you are using css modules . Did you set config for using css module as the course ?? I must mention that you can use css module without running 'npm run eject' and these complicated config as React 2 support css modules you just need to change the extension from .css to .module.css

Here is the clean code for your :

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
like image 24
ShifaT Avatar answered Oct 12 '22 11:10

ShifaT


//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
like image 29
Shivam Lakhwara Avatar answered Oct 12 '22 11:10

Shivam Lakhwara