Importing useState - not available for all projects?

I wanted to give myself some extra practice using React hooks so I made a fork of the Copy Cat project and decided I would try to convert the class components to functions.

I could not make it work.

After far, faaaaar more hours than I would care to admit… I’m wondering if the option to import useState from the React library is not available in that project.

As in this:

import React, { useState } from 'react';

Can someone confirm this for me?

I don’t think issue was from an error. I was able to change the presentational component, but the container would not function when I converted this.setState to a useState method. When I tried changing the props to either null or their default state on the container side it would display, just with no functionality. I could also swap the tape on/off by manually changing ‘copying’ from true to false in the container. I even tried making an extra component I tacked on at the end with a really basic hook and that didn’t work either.

I’ve posted my code below (minus all the experiments I did along the way). If the issue isn’t importing useState can someone take a look and see what I did wrong?? I’ve been staring at this so long I’ve gone cross-eyed.

Many thanks.
N

CopyCatContainer.js
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
import { CopyCat } from '../components/CopyCat.js';

function CopyCatContainer() {
  const [copying, setCopying] = useState(true);
  const toggleTape = () => { setCopying(!copying) };
  const [input, setInput] = useState('');
  const handleChange = (e) => { setInput(e.target.value) };
  const value = input;
  return (
      <CopyCat copying={copying} toggleTape={toggleTape} value={value} handleChange={handleChange} />
  )
}

ReactDOM.render(<CopyCatContainer />, document.getElementById('app'));
CopyCat.js
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { styles } from '../styles.js'

const images = {
  copycat: 'https://content.codecademy.com/courses/React/react_photo_copycat.png',
  quietcat: 'https://content.codecademy.com/courses/React/react_photo_quietcat.png'
};

export function CopyCat(props) {
  const {copying, toggleTape, value, handleChange, name} = props;
  
  return (
    <div style={styles.divStyles}>
        <h1 style={{marginBottom: 80}}>Copy Cat {name || 'Tom'}</h1>
        <input 
          type='text' 
          value={value}
          onChange={handleChange}
        />
        <img 
          style={styles.imgStyles} 
          alt='cat'
          src={copying ? images.copycat : images.quietcat}
          onClick={toggleTape}
        />
        <p>{copying && value}</p>
      </div>
  )
}

CopyCat.propTypes = {
  copying: PropTypes.bool.isRequired,
  toggleTape: PropTypes.func.isRequired,
  value: PropTypes.string.isRequired,
  handleChange: PropTypes.func.isRequired,
  name: PropTypes.string
}

Hi,

your import statement looks fine and should work.

From a first glance I don’t see why it wouldn’t work except that you might need to explicitly pass the event argument when you call ‘handleChange’ like this:

onChange={ e => handleChange(e) }

Have you tried to log the event in your CopyCatContainer component?

const handleChange = (e) => { 
console.log(e)
setInput(e.target.value) 
};

That way you see if the function is executed in the first place. If it logs ‘undefined’, my suggestion above should fix the issue.

1 Like

Thanks for your reply mirja. I should clarify, I wasn’t looking for confirmation that I had correctly written the import statement, but I can see how it looks like that based on how I worded the question.

I want to know: Are some project libraries set up without the ability to import useState() from react? - As I described in my first post, I went off-lesson making this fork because I wanted to practice hooks. So maybe because the original project does not require useState(), perhaps its not part of the library set up by the course’s writers?

It’s definitely looking like this might be the case, because I tested the code, just as I posted above, in a React app install on my own computer and it worked.

Is there anyone with inside knowledge about how the projects are set up who can answer this?

useState is included in the React library. You can import and use it in functional components.
Maybe you should provide more information about how you set up your project locally: Did you run npx create-react-app yourappsname or did you download the project folder from Codecademy/fork it from their repo and ran npm install? What does your package.json look like?

What other libraries than React do you mean?

1 Like

Then I am out of ideas… my only theory was the library you are importing React from in the Codacademy workspace is not complete somehow. Like maybe it was a facsimile, written to be imported the same way you would use it outside of this environment but paired down to only what was needed in the exercise to save space?? It may be that React doesn’t work that way, but it was all I could think of when all the variations of the code I tested worked fine until I would try to add useState()

When I tested this on my own I used a project I was already working on independently that I set up using npx create-react-app - I copied the content of the files CopyCat.js, CopyCatContainer.js, styles.js, and index.css into a subfolder.

The only change from the original version is that I exported the CopyCatContainer function and took out the line

ReactDOM.render(<CopyCatContainer />, document.getElementById('app'));

Instead I swapped <CopyCatContainer /> to the App.js file that comes with the default install, which then gets rendered in index.js

Obviously in all cases I updated the import paths to match the modified folder set up, but apart from that and changing where the component is rendered, nothing was changed from the original code I posted above. The content in both components was not changed at all.

I don’t think I ever touched the package.json, so it should be in the default state it comes in when you run create-react-app. (I’m very new to using VSCode and it’s… a steep learning curve.)

package.json
{
  "name": "notes-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^13.2.0",
    "@testing-library/user-event": "^13.5.0",
    "react": "^18.1.0",
    "react-dom": "^18.1.0",
    "react-scripts": "^2.1.3",
    "web-vitals": "^2.1.4",
    "websocket-driver": "^0.7.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

To be clear, I’m pretty proficient in Javascript but I a newcomer to React, and not very comfortable yet using VSCode or anything that requires the Terminal. So I wouldn’t surprised if I made an error in my code, or when I was setting up my local React install / work environment, but that doesn’t seem to be the case given it worked fine on localhost, but not in Codecademy.

Thanks for all your attention on this.

Just to be sure what you did this time and how the result deviates from what you expect:
You wrote you forked the project:

  • Did you fork it from Codecademy’s GitHub Repo?
  • If so: Did you run npm install?
  • Do you have a node_modules folder in your project folder?

What happens when you run your app? Nothing at all or is it just the state that is not updating? What makes you think it is about the useState hook?

Otherwise if you do that in the Codecademy environment / sandbox (not sure what you mean by “forking”, please provide a link to the lesson.

1 Like

I just pressed ‘Fork’ in the top menu, it’s classified as a ‘Workspace’ and can be accessed from my dashboard. So no npm install

There is no node_modules folder, I believe the folders are the default ones from the project.

Here’s a link to my workspace, I’ve saved it use the non-functioning CopyCatContainer function, so when you load it the display screen should be blank.

https://www.codecademy.com/workspaces/627d5356733b68a5929aee07

I don’t get any error messages when I run my function, presumably because the CopyCatContainer.compiled.js file included with the project is formatted to the original class component set-up, and doesn’t recognize what I’m doing.

However, when I change the CopyCatContainer function to not use useState(), and define the props as either null or their default state value, the app runs - but without the functionality of toggleTape() and handleChange() (since both function values are null). It’s clearly passing values, because if I switch the value copying from true to false, it changes the picture. I can also pass in a name, which otherwise appears as the default ‘Tom’. Pasted below:

Modified function
function CopyCatContainer() {
  let copying = true;
  const toggleTape = null;
  const input = '';
  const value = input;
  const handleChange = null;
  return (
      <CopyCat copying={copying} toggleTape={toggleTape} value={value} handleChange={handleChange} name='Jeff' />
  )
  }

Here’s a screenshot, you can see all the folders/files (I genuinely can’t remember if I added the folder ‘Test’ or if it was there already, but it’s empty, and I know I didn’t delete anything, so it’s probably not important.
As you can see, when I use my dummy version of the function, the app runs.

Screenshot

Another reason I think it’s the statehook and not the rest of the code is because while testing yesterday, I tried adding a really simple extra component that also used the statehook, and that didn’t work either. But when I tried plugging that same extra component into another Codecademy workspace that already used useState it worked! I don’t have the code for it anymore, it was a simple toggle button that changed text if it was true or false.

Once again, thanks for following up on this.

Ok, when I fork my project and copy your code, I get this error:

TypeError: (0 , _react.useState) is not a function

That indicates an issue with the React version:

I have done this project quite a while ago and it was class based. Functional components and hooks were introduced later than class components – in React v16.8.

We cannot see which version is installed in the Codecademy environment, but the first version of the React course was developed prior to the release of hooks. So it is possible that the version installed is too old and therefore does not export hooks. Your code is fine from what I can see, it must be something related to the React installation done by Codecademy.

1 Like

Wow. Thank you for all this.

It feels pretty good knowing this wasn’t all in my head. Great sleuthing!

I will mark this down as solved :+1:

1 Like