'Unexpected token "const [xxx, setXxx] = useState"

I'm creating a project with React and Django to allow users to sign up and log in.

Whenenver I run my project (with npm start) though, I keep getting this error:

./src/components/signup_components/Signup.js
  Line 15:11:  Parsing error: Unexpected token

  13 |         err:null
  14 |     }
> 15 |     const [email,setEmail] = useState('');
     |           ^
  16 |     const [password1, setPassword1] = useState('');
  17 |     const [location, setLocation] = useState('');
  18 |     const [errors,setErrors] = useState(false);

Here's my code:

Login.js

import React, { Component,useState,useEffect } from "react";
import secure_login from "../../assets/images/secure_login.svg"
import "../../assets/scss/core/signup_components/_signup.scss"

export default class Login extends Component {
    constructor(props) {
        super(props);
    }
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    const [errors, setErrors] = useState(false);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        if (localStorage.getItem('token') !==null) {
            window.location.replace('http://localhost:3000/profile');
        } else {
            setLoading(false);
        }
    }, []);

    const onSubmit = e => {
        e.preventDefault();
    }

    const user = {
        email: email,
        password: password
    };

    fetch('http://127.0.0.1:8000/api/v1/users/', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(user)
    })
        .then(res => console.log(res.json()))
        .then(data => {
            if(data.key) {
                localStorage.clear();
                localStorage.setItem('token',data.key);
                window.location.replace('http://localhost:3000/profile');
            } else {
                setEmail('');
                setPassword('');
                localStorage.clear();
                setErrors(true);
            }
        });
    };

    render() {
    return (
      <div className="base-container" ref={this.props.containerRef}>
        <div className="header">Login</div>
        <div className="content">
          <div className="image">
            <img src={secure_login} />
          </div>
          <div className="form">
            <div className="form-group">
              <label htmlFor="username">Username</label>
              <input type="text" name="username" placeholder="username" />
            </div>
            <div className="form-group">
              <label htmlFor="password">Password</label>
              <input type="password" name="password" placeholder="password" />
            </div>
          </div>
        </div>
        <div className="footer">
          <button type="button" className="btn">
            Login
          </button>
        </div>
      </div>
    );
  }
}

Signup.js

import React, { Component,useState,useEffect } from "react";
import secure_signup from "../../assets/images/secure_signup.svg"
import CountrySelector from './CountryList'
import ProcessImage from 'react-imgpro';


export default class Signup extends Component {
    constructor(props) {
        super(props);
    }
    state= {
        src:'',
        err:null
    }
    const [email,setEmail] = useState('');
    const [password1, setPassword1] = useState('');
    const [location, setLocation] = useState('');
    const [errors,setErrors] = useState(false);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        if(localStorage.getItem('token') !== null) {
            window.location.replace('http://localhost:3000/profile');
        } else {
            setLoading(false);
        }
    }, []);

    const onSubmit = e => {
        e.preventDefault();

        const user = {
            email: email,
            password: password,
            location: location
        };

        fetch('http://127.0.0.1:8000/api/v1/users/profiles/', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(user)
            })
            .then(res => res.json())
            .then(data => {
                if(data.key) {
                    localStorage.clear();
                    localStorage.setItem('token',data.key);
                    window.location.replace('http://localhost:3000/profile');
                } else {
                    setEmail('');
                    setPassword1('')
                    setLocation('')
                    localStorage.clear();
                    setErrors(true);
                }
            });
        }
    }
      render() {
        return (
            <div className="base-container" ref={this.props.containerRef}>
                {loading === false && <div className="header">Register</div> }
                {errors === true && <h2>Cannot signup with provided credentials</h2>}
                <div className="content">
                    <div className="image">
                        <ProcessImage
                            image={secure_signup}
                            resize={{ width:400, height: 400 }}
                            processedImage={(src,err) => this.setState({ src,err})}
                            />
                    </div>
                    <div className="form">
                        <div className="form-group">
                            <label htmlFor="username">Username</label>
                            <input
                                type="text"
                                name="name"
                                placeholder="name"
                                value={name}
                                onChange={e => setEmail(e.target.value)}
                                required
                            />{' '}
                        </div>
                        <div className="form-group">
                            <label htmlFor="email">Email</label>
                            <input
                                type="text"
                                name="email"
                                placeholder="email"
                                value={email}
                                onChange={e => setEmail(e.target.value)}
                                required
                            />{' '}
                        </div>
                        <div className="form-group">
                            <label htmlFor="location">Location</label>
                            <CountrySelector />
                        </div>
                        <div className="form-group">
                            <label htmlFor="password">Password</label>
                            <input
                                type="text"
                                name="password"
                                placeholder="password"
                                value={password}
                                onChange={e => setPassword1(e.target.value)}
                                required
                            />
                        </div>
                    </div>
                </div>
            <div className="footer">
                <button type="button" className="btn" onClick={onSubmit}>
                    Register
                </button>
            </div>
        </div>
      );
    }
}

App.js

import React, { useRef, useEffect } from 'react';
import { useLocation, Switch } from 'react-router-dom';
import AppRoute from './utils/AppRoute';
import ScrollReveal from './utils/ScrollReveal';
import ReactGA from 'react-ga';
import Login from './components/login_components/Login';
import Signup from './components/signup_components/Signup'
import Profile from './components/profile_components/Profile'

// Layouts
import LayoutDefault from './layouts/LayoutDefault';

// Views 
import Home from './views/Home';

// Initialize Google Analytics
ReactGA.initialize(process.env.REACT_APP_GA_CODE);

const trackPage = page => {
  ReactGA.set({ page });
  ReactGA.pageview(page);
};

const App = () => {

  const childRef = useRef();
  let location = useLocation();

  useEffect(() => {
    const page = location.pathname;
    document.body.classList.add('is-loaded')
    childRef.current.init();
    trackPage(page);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [location]);

  return (
    <ScrollReveal
      ref={childRef}
      children={() => (
        <Switch>
          <AppRoute exact path="/" component={Home} layout={LayoutDefault} />
          <AppRoute exact path="/login" component={Login} />
          <AppRoute exact path="/signup" component={Signup} />
          <AppRoute exact path="/profile" component={Profile} />
        </Switch>
      )} />
  );
}

export default App;

I don't get where the unexpected token error is coming from. Can anyone explain to me why this is happening and how to fix it?



Solution 1:[1]

Before I correct your error, your implementation first needs some fixing. (All your problems originate from Signup.js.)

The concept of React hooks (any function starting with use) was invented to allow React functional components to do things that used to be only able to be done with class components, for example, in class components you might write (in the constructor):

this.state = {
  name: "John",
  age: 23
};

To access the state:

this.state.name // <-- "John"

Then to modify the state you do:

this.setState({ ...this.state, age: 292 });

Setting the state causes the component to rerender and modifies the UI as such.

To do this in functional components, there's a built-in hook called useState, used something like (inside your functional component):

const [name, setName] = useState("John");
const [age, setAge] = useState(23);

To access the state's name, you simply do:

name // <-- "John"

and to modify it:

setName("Jane");

So the problem with your code is that you're trying to use hooks for class components, which already has those built in features. You got it right when you wrote:

state = {
  src: "",
  err: null
}

Now, you have the task of moving everything else into that state declaration:

state = {
  src: "",
  err: null,
  email: "",
  password1: "",
  location: "",
  errors: false,
  loading: true
}

And to access the state you'd do:

this.state.password1 // <-- ""

or

this.state.loading // true

And to set the state:

this.setState({ ...this.state, loading: false, password: "e34O#*Nre" });

You're also using the useEffect hook. Change that to componentDidMount() {...}.

However, in App.js you are creating a functional component, so everything works just fine.

Now for your error...
There are 2 ways to declare class-scoped variables (and your way isn't one of them):

  1. Inside any class method (generally in the constructor), declare it with this.variableName = value
  2. Outside of all class methods, declare it with variableName = value

In both ways of declaration they are read with this.variableName.

So that's why JavaScript complained at you.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Phil