1
votes

I get this error when trying to npm start my project:

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
import React, { useState, useEffect } from 'react';
import './index.css';
import conspireLogo from './conspireLogo.png';
import Post from './Post'
import { auth, db } from './firebase';
import { makeStyles } from '@material-ui/core/styles';
import Modal from '@material-ui/core/Modal';
import { Button, Input } from '@material-ui/core'
import ImageUpload from './imageUpload';
//import { BrowserRouter, Route, Switch } from 'react-router-dom';

function getModalStyle() {
  const top = 50;
  const left = 50;

  return {
    top: `${top}%`,
    left: `${left}%`,
    transform: `translate(-${top}%, -${left}%)`,
  };
}

const useStyles = makeStyles((theme) => ({
  paper: {
    position: 'absolute',
    width: 400,
    backgroundColor: theme.palette.background.paper,
    border: '2px solid #000',
    boxShadow: theme.shadows[5],
    padding: theme.spacing(2, 4, 3),
  },
}));

function MainPage() {
  const classes = useStyles();
  const [modalStyle] = useState(getModalStyle);

  const [posts, setPosts] = useState([]);
  const [open, setOpen] = useState(false);
  const [openSignIn, setOpenSignIn] = useState(false);
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [email, setEmail] = useState('');
  const [user, setUser] = useState(null);

  useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged((authUser) => {
      if (authUser) {
        console.log(authUser);
        setUser(authUser);      
      } else {
        setUser(null);
      }
    })

    return () => {
      unsubscribe();
    }
  }, [user,username]);

  useEffect(() => {
    db.collection('posts').orderBy('timestamp', 'desc').onSnapshot(snapshot => {
      setPosts(snapshot.docs.map(doc => ({
        id: doc.id,
        post: doc.data()
      })));
    })
  }, []);

  const signUp = (event) => {
    event.preventDefault();

    auth
    .createUserWithEmailAndPassword(email, password)
    .then((authUser) => {
      authUser.user.updateProfile({
        displayName: username
      })
    })
    .catch((error) => alert(error.message));
  }

  const signIn = (event) => {
    event.preventDefault();

    auth
    .signInWithEmailAndPassword(email, password)
    .catch((error) => alert(error.message));

  setOpenSignIn(false);
  }

  return (
    <div className="app">
      <Modal
        open={open}
        onClose={() => setOpen(false)}
      >
        <div style={modalStyle} className={classes.paper}>
        <form className="app__signup">
          <center>
            <img
              className="app__headerImage"
              src={conspireLogo}
              alt="Conspire Logo"
            />
            </center>
            <Input
              placeholder="username"
              type="text"
              value={username}
              onChange={(e) => setUsername(e.target.value)}
            />
            <Input
              placeholder="email"
              type="text"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
            />
            <Input
              placeholder="password"
              type="password"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
            />
            <Button type="submit" onClick={signUp}>Sign Up</Button>
          </form>
        </div>
      </Modal>

      <Modal
        open={openSignIn}
        onClose={() => setOpenSignIn(false)}
      >
        <div style={modalStyle} className={classes.paper}>
        <form className="app__signup">
          <center>
            <img
              className="app__headerImage"
              src={conspireLogo}
              alt="Conspire Logo"
            />
            </center>
            <Input
              placeholder="email"
              type="text"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
            />
            <Input
              placeholder="password"
              type="password"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
            />
            <Button type="submit" onClick={signIn}>Sign In</Button>
          </form>
        </div>
      </Modal>

    <div className="app__header">
      <img
        className="app__headerImage"
        src={conspireLogo}
        alt="Conspire Logo"
    />
    {user ? (
      <Button onClick={() => auth.signOut()}>Logout</Button>
    ): (
      <div className="app__loginContainer">
        <Button onClick={() => setOpenSignIn(true)}>Sign In</Button>
        <Button onClick={() => setOpen(true)}>Sign Up</Button>
      </div>
    )}
    </div>
    
    <div className="app__footer">
      <Button onClick={() => setOpenSignIn(true)}><img
        className="app__footerImage"
        src="http://www.simpleimageresizer.com/_uploads/photos/bdfbb0d1/346a1f4363e1b59f6860fdce6abc1082_2_15.jpg"
        alt="Create"
      />
      </Button>
    </div>

    <div className="app__posts">
      <div className="app__postsLeft">
      {
        posts.map(({id, post}) => (
          <Post key={id} postId={id} user={user} username={post.username} caption={post.caption} imageUrl={post.imageUrl}></Post>
        ))
      }
      </div>
     </div>

    {user?.displayName ? (
        <ImageUpload username={user.displayName} />
      ): (
        <h3 className="center">Sorry you need to login to upload</h3>
      )}
  
    </div>

  );
}

export default MainPage;
2
Why are you using useEffect hook twice?Bélgica
could you please share your pakage.jsonSanat Gupta
@Bélgica one effect runs only once after mount, the other every time its dependencies change. This is unrelated, but getModalStyle should just be an object literal. You are currently assigning a function to the style prop, not its return value. You don't need the function or useState at all for that.hotpink
Hey :) Is there no stack trace or similar attached to the error? If there is, it would be really helpful if you share that.Elias

2 Answers

0
votes
const [modalStyle] = useState(getModalStyle);

You're storing the function reference, not the function's return. Change it to

const [modalStyle] = useState(getModalStyle());

Moreover as you don't need to change this modalStyle, you don't need to have it in state

<div style={getModalStyle()} className={classes.paper}>
0
votes

I don't think so there should be any error in this file, please check the other files ex - Post, ImageUpload