Matt
Matt

Reputation: 73

React element is not defined

Why is 'SearchBar' is giving me the error:

"MovieList.js:24 Uncaught ReferenceError: SearchBar is not defined at MovieList.render (MovieList.js:24) at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (react-with-addons.js:6336)"

While 'Movie' works fine. I don't see the difference between the structure of the Movie component vs the SearchBar component. When I render the SearchBar component with ReactDOM.render on the bottom of its page, it has functionality. The list of movies shows up as desired on the page when I remove the SearchBar element from the parent component's page.

Here is my code for all three components involved: Parent:

class MovieList extends React.Component {
  constructor() {
    super();
    this.state = {
      movies: [
        { title: 'Mean Girls' },
        { title: 'Hackers' },
        { title: 'The Grey' },
        { title: 'Sunshine' },
        { title: 'Ex Machina' }
      ]
    };
  }


  render() {

    var movies = this.state.movies;
    console.log(movies);

    return (
      <div>

        <SearchBar />

        {movies.map((movie) =>
          <Movie movie={movie}/>
        )}

      </div>
    )
  }
}

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

window.MovieList = MovieList;

SearchBar:

class SearchBar extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: ''
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);

  }

  handleChange(event) {
    this.setState({
      value: event.target.value
    });
  }

  handleSubmit(event) {
    console.log(this.state.value);
  }

  render() {
    return (
      <div>
        <input type='text' value={this.state.value} onChange={this.handleChange} />
        <button onClick={this.handleSubmit}>Search</button>
      </div>
    )
  }
}


window.SearchBar = SearchBar;

Movie:

class Movie extends React.Component {
  constructor(props) {
    super(props);
    // this.state = {
    //
    // };
  }

  render() {
    return (
      <div className="movie-title">{this.props.movie.title}</div>
    )
  }
}

window.Movie = Movie;

Upvotes: 1

Views: 5148

Answers (4)

stealththeninja
stealththeninja

Reputation: 3791

Seeing as the components are declared as global variables (window.SearchBar = SearchBar) rather than module imports, I'm wondering your files are imported in alphabetical order:

<script src="./Movie.js"></script>
<script src="./MovieList.js"></script>
<script src="./SearchBar.js"></script>

If this is the case, child components should be imported before a parent component.

<!-- children -->
<script src="./Movie.js"></script>
<script src="./SearchBar.js"></script>
<!-- parent -->
<script src="./MovieList.js"></script>

The other answers nudge at module loading which I'd encourage you to look into if you're building anything more than a prototype.

Upvotes: 0

nick
nick

Reputation: 2853

at the bottom of your SearchBar component you should have

export default SearchBar;

then at the top of your MovieList component, you should import the SearchBar component.

import SearchBar from './SearchBar'

Upvotes: 1

Bhojendra Rauniyar
Bhojendra Rauniyar

Reputation: 85545

Defining variable in window will not work implicitly in other files. You need to require that file to use:

require('SearchBar.js')

But this is generally not suitable way. Global variables may conflict if your application size grows. You would export the class and import them to use:

// SearchBar.js
export default SearchBar // instead of defining window.SearchBar
// MovieList.js
import SearchBar from './SearchBar'

Now, you can use SearchBar component.

Upvotes: 1

Rohith Murali
Rohith Murali

Reputation: 5669

Try after importing SearchBar component using an import statement,

Eg, import SearchBar from './SearchBar'

Upvotes: 0

Related Questions