3

I'm building a React app and attempting to update some JavaScript functions to use ES6 destructured arrow syntax.

Index.js file:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

function TestMe() {
  const name = "User";
  const message = "Welcome!";
  return (
    <div>
      <Hello name={name} />
      <Message message={message} />
    </div>
  );
}

ReactDOM.render(<TestMe/>, document.querySelector('#root'));

const Hello = ({ name }) => (
    <span>Hello, {name}</span>
);

function Message(props) {
  return (
    <div className="message">
      {props.message}
    </div>
  );
}

The Message function will render, but the Hello function throws the following error in the browser (after successful build):

""" Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of TestMe. """

Here's my package.json, just in case:

{
  "name": "jsx-exercises",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "eslint": "^5.6.0",
    "react": "^16.7.0",
    "react-dom": "^16.7.0",
    "react-scripts": "2.1.2"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ]
}

Why am I getting this error?

3
  • 3
    What happens if you move const Hello in front of the function TestMe ? Commented Dec 29, 2018 at 14:26
  • 3
    Look up "function declaration/function expression hoisting" and their differences. Commented Dec 29, 2018 at 14:31
  • stackoverflow.com/questions/10081593/… Commented Dec 29, 2018 at 14:47

2 Answers 2

1

Declarations in Javascript get "hoisted", which means that they can be accessed in the whole scope, even before they are declared. If you use a function declaration also the initialization happens when the scope starts:

 { // scope begins
   a();
   function a() { }
 } // scope ends

Now variables can only be accessed after they were initialized:

 setTimeout(() => console.log(a)); // 1
 console.log(a); // undefined
 var a = 1;

In your case you access Hello before it was initialized.


Fun fact: Accessing variables declared with let or const before the initialization happened throws a SyntaxError (for a good reason, q.e.d.) so one can see that your building pipeline replaced const with var to support older browsers.

Sign up to request clarification or add additional context in comments.

2 Comments

Great tips, too! Thank you!
@lane glad to help :)
0

You must move Hello on the top of your file, because TestMe can't see this const. Functions javascript can see anyway, because it's function declaration

2 Comments

"can't see this const" ... what?
your function inside constant

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.