btholt / complete-intro-to-react

A Complete Intro to React, as Given for Frontend Masters
https://frontendmasters.com/learn/react/
MIT License
1.06k stars 929 forks source link

Flow outdated in v3 of the course #109

Open Pitt-Pauly opened 6 years ago

Pitt-Pauly commented 6 years ago

I am working my way through version 3 of the Complete Intro to React course and when it came to the Flow chapter (integrating Types to JS and React) I had a lot of problems getting Flow to work. It turned out to be mainly a versioning issue between flow and flow-typed (and their repos containing the type definitions).

I have resolved these issues by upgrading both flow (or rather flow-bin) and flow-typed to a recent version, and using the new Flow syntax.

I wanted to share my solution so anyone working through the course now could hopefully save some time. Also I used VSCode rather than Sublime, so if you have any questions on how to integrate Flow with VSCode, let me know!

Here is what I did:

First remove flow and flow-typed: $ yarn remove flow-bin flow-typed flow

then install it again as a developer dependency: $ yarn add --dev flow-bin flow-typed

You can check the new versions are installed in package.json under dev:

"devDependencies": {
   [...]
    "flow-bin": "^0.77.0",
    "flow-typed": "^2.5.1",

Note: Depending on when you run the commands these version numbers may be higher than what I have here.

Now follow the course along (Flow chapter), to setup (yarn flow init) and get the type definitions (yarn flow-typed install) and check you added the styledcomponents to the [ignored] and [libs] section in the .flowconfig.

Ie. your .flowconfig file looks like this:

[ignore]
<PROJECT_ROOT>/node_modules/styled-components/*

[include]

[libs]
styled-components

[lints]

[options]

[strict]

Now you will still get errors when you add the flow annotation (// @flow) to the Search.jsx page. This is because you are now using a new version of Flow, and they updated their syntax. To read up on some differences check out these resources:

Implementing the new syntax your Search.jsx file will look like this now:

// @flow

import * as React from 'react';
import preload from '../data.json';
import ShowCard from './ShowCard';

type State = {
  searchTerm: string
};

class Search extends React.Component<void, State> {
  state = {
    searchTerm: ''
  };

  handleSearchTermChange = (
    event: SyntheticKeyboardEvent<HTMLInputElement>
  ) => {
    this.setState({ searchTerm: event.currentTarget.value });
  };

  render() {
    return (
      <div className="search">
        <header>
          <h1>h4p1 video</h1>
          <input
            onChange={this.handleSearchTermChange}
            value={this.state.searchTerm}
            type="text"
            placeholder="Search"
          />
        </header>
        <div>
          {preload.shows
            .filter(
              show =>
                `${show.title} ${show.description}`
                  .toUpperCase()
                  .indexOf(this.state.searchTerm.toUpperCase()) >= 0
            )
            .map(show => <ShowCard {...show} key={show.imdbID} />)}
        </div>
      </div>
    );
  }
}

export default Search;
ekzor commented 6 years ago

thank you so much for your post! I've spent most of my day trying to get through this step of the tutorial and this has definitely helped.

Out of curiosity, did you run into any trouble with flow not finding your react components or the json file? it's telling me that it Cannot resolve module ../data.json (and same for ./ShowCard). i'm wondering if this has something to do with installing flow globally vs into the node_modules directory... and after a lot of searching online it doesn't seem anyone else has had a problem like this :(

Pitt-Pauly commented 6 years ago

Great! I'm glad I could help a little :)

The problem with resolving the ../data.json and ./ShowCard module could related to the way I imported React. In Search.jsx, try changing line 3 as follows: Replace import * as React from 'react'; With import React, { Component } from 'react'; and on line 9: Replace class Search extends React.Component<void, State> { With class Search extends Component<void, State> {

Does that resolve the issue?

ekzor commented 6 years ago

Unfortunately I had already tried that because I noticed it in your post. I get the same error regardless of how I import React. I've even tried downgrading flow back to what btholt uses in his tutorial but I still get the same error. From what I can tell in my searching, it has something to do with flow-type files for these modules missing, but when I tried to create one it didn't matter.

Then I got to thinking that it might be something to do with babel not interpreting the file inclusion correctly, so that's the next aspect I intend to tackle. I've been stuck on this for two days and I refuse to give up. Any ideas would be greatly appreciated.

Also my apologies, as I realize this is veering off-topic from your original post!

Pitt-Pauly commented 6 years ago

Have you tried checking out the official version of the file without flow? Was it working then? I don't see how flow could have anything to do with importing the data.json or the other module tbh. So have a look at the official repo's verison, and as a reference here is my fork of the repo as well: https://github.com/Pitt-Pauly/complete-intro-to-react/commits/start I have a build on top of the start branch, and finished the course today so it should be complete in terms of updated flow types.

Also don't get bogged down by this since later in the course the Search module will change so just keep on going ;)

ekzor commented 6 years ago

Thanks a lot for pointing me to your fork, and for the encouragement. Despite starting from your fork, I'm still getting the same errors in flow. it must be something wrong with my system... I may have to skip this part until I can sort it out. Thanks again.

Pitt-Pauly commented 6 years ago

hm, I checked again and the flow commit on my fork commit is working for me. did you do git checkout c4d0618c623c95e01ddc760ebe918d0bd41adf9a to see if it works or did you do git checkout start?

ekzor commented 6 years ago

Thanks for all your help @Pitt-Pauly! I had actually already started from that commit and it was no use. That being said, I finally solved the problem after 3 long days of troubleshooting!

And since somebody else will inevitably come across this thread when searching for why they keep getting 'cannot resolve module' for their project files/react modules: The problem was Cygwin. flow works fine when invoked from the Windows cmd prompt, it's just the Cygwin prompt that was breaking it (even though it was being run via yarn in both cases).

I'll submit this as a bug to both flow and cygwin and they can figure out whose fault it is (or maybe I'll dig into the code to see if I can puzzle it out myself), since Windows console apps are supposed to work the same under Cygwin as they do in cmd.

Sorry again for hijacking your thread! Hopefully this helps somebody else in the same situation.

biblicalph commented 6 years ago

I run into the error cannot call render with document.getElementById(...) bound to container because null is incompatible with ... - see the attached image for more details

screen shot 2018-08-14 at 5 04 30 pm

I applied the solution proposed in this StackOverflow question to resolve it.

It basically says you should change the renderApp function to:

const renderApp = () => {
    const appElement = document.getElementById('app')

    if (appElement) {
           render(<App />, appElement)
    }
}

Hope this helps