React.js Frequently Faced Problems

At jsComplete, we manage a slack account dedicated to helping code learners get unstuck. We receive some interesting problems every now and then but most of the asked questions are for common problems. I am creating this resource to write detailed instructions for the common problems beginner React.js learners usually face so that I can refer them to here instead of typing it over and over.

1 — Not starting a component name with a capital letter

A React component must have a name which starts with a capital letter.

If the component name does not start with a capital letter, the component use will be treated as a built-in element such as a div or span.

For example:

classgreetingextendsReact.Component{// ...}

If you try to render <greeting />, React will ignore the above and you will get a warning:

Warning: The tag <greeting> is unrecognized in this browser.
If you meant to render a React component,
start its name with an uppercase letter.

The bigger problem here is when you decide to name your component button or img. React will ignore your component and just render a vanilla HTML button or img tag.

Note how the “My Awesome Button” was not rendered above and React just rendered an empty HTML button element. React will not warn you in this case.

2 — Using single quotes instead of back-ticks

Strings created with back-ticks (`...`) are different from strings created with single quotes ('...').

On most keyboards, the back-tick (`) character can be typed using the key above the tab key.

We create a string using back-ticks when we need to include dynamic expressions inside that string (without resorting to string concatenation).

`This is a string template literal that can include expressions`'This is just a string, you cannot include expressions here'

Let’s say you want a string that always reports the current time:

“Time is ...”

// Current time stringconsttime=newDate().toLocaleTimeString();// When using regular strings (single or double quotes),// you need to use string concatenation:'Time is '+time// When using back-ticks,// you can inject the time in the string using ${}`Time is ${time}`

Also, when using string literals (with back-ticks), you can create a string that spans multiple lines:

consttemplate=`I
CAN
SPAN
Multiple Lines`;

You can’t do that with regular strings.

3— Using React.PropTypes

The PropTypes object was removed from React. It used to be available as React.PropTypes but you cannot use that anymore.

4 — Not using the right versions of what a tutorial is using

When watching or reading content about coding and following up with the examples they present, make sure that you are using correct versions of the tools the content is using. Usually, using the latest version of each tool is a safe bet, but if the content is a bit old you might run into some deprecation issues.

To be safe, stick with the major versions for the used tools. For example, if the tutorial is using React 16, don’t follow up using React 15.

This is especially important for Node.js as well. You will face major problems if you use an older version of Node. For example, if you’re following along with some tutorial that uses Object.values and you are using Node 6.x, that method did not exist back then. You need Node 7.x or higher.

Using {7}, inside the Greeting component, this.props.counter will have the actual numeric 7 value and it will be safe to do mathematical operations on that. If you pass it as “7” and then treat it as a number, you might run into unexpected results.

7 — Forgetting that another app instance is still using the same port

To run a web server, your need to use a host (like 127.0.0.1) and a port (like 8080) to make the server listen for request on a valid http address.

Once the web server is running successfully, it has control over that port. You cannot use the same port for anything else. The port will be busy.

If you try to run the same server in another terminal, you’ll get an error that the port is “in use”. Something like:

Error: listen EADDRINUSE 127.0.0.1:8080

Be aware that sometimes a web server might be running in the background or inside a detached screen/tmux session. You don’t see it, but it is still occupying the port. To restart your server, you need to “kill” the one that’s still running.

To identify the process that’s using a certain port, you can either use a command like ps (and grep for something about your app) or if you know the port number you can use the lsof command:

lsof -i :8080

8 — Forgetting to create environment variables

Some projects depend on the existence of shell environment variables in order to start. If you run these projects without the needed environment variables, they will try to use undefined values for them and will potentially give you some cryptic errors.

For example, if a project connects to a database like MongoDB, chances are it uses an environment variable like process.env.MONGO_URI to connect to it. This allows the project to be used with different MongoDB instances in different environments.

To locally run the project that connects to a MongoDB, you have to export a MONGO_URI environment variable first. For example, if you have a local MongoDB running on port 27017, you would need to do this before running the project:

export MONGO_URI="mongodb://localhost:27017/mydb"

You can grep the project source code for process.env to figure out what environment variables it needs in order to work correctly.

9— Confusing curly braces {} with parentheses ()

Instead of:

return{something();};

You need:

return(something(););

The first one will try (and fail) to return an object while the second one will correctly call the something() function and return what that function returns.

Since any <tag> in JSX will translate to a function call, this problem applies when returning any JSX.

This problem is also common in arrow functions’ short syntax.

Instead of:

constGreeting=()=>{<div>HelloWorld</div>
};

You need:

constGreeting=()=>(<div>
Hello World
</div>);

When you use curly braces with an arrow function, you are starting the scope of that function. The short syntax of arrow functions does not use curly braces.

10 — Not wrapping objects with parentheses

The curly braces vs. parentheses problem above is also confusing when you want to create a short arrow function that returns a plain-old object.

Instead of:

constmyAction=()=>{type:'DO_THIS'};

You need:

constmyAction=()=>({type:'DO_THIS'});

Without wrapping the object in parentheses, you would not be using the short syntax. You will actually be defining a label for a string!

This is common inside the updater function of the setState method because it needs to return an object. You need to wrap that object with parenthesis if you want to use the short arrow function syntax.

11 — Not using the right capitalization of API elements and props

Pay attention to the API capitalization that you need. If you use incorrect capitalization, the errors you’ll get might not clearly state what the problem is.

When importing from react and react-dom, make sure that you’re importing the correct names and what you’re using is exactly the same as what you’re importing. ESLint can help you point out what is not being used.

If, instead of props.userName, you incorrectly use props.username or props.UserName, you will be using an undefined value. Pay attention to that, or better yet, make your ESLint configuration point these problems out as well.

12— Confusing the state object with instance properties

In a class component, you can define a local state object and later access it with this:

The state instance property is a special one because React will manage it. You can only change it through setState and React will react when you do. However, all other instance properties that you define will have no effect on the rendering algorithm. You can change this.user in the above example as you wish and React will not trigger a render cycle in React.

13 — Confusing <tag/> with </tag>

Don’t misplace the / character in your closing tags. Admittedly, sometimes you can use <tag/> and other times you need </tag>.

In HTML, there is something called a “self-closing tag” (AKA void tag). Those are the tags representing elements that do not have any children nodes. For example, the img tag is a self-closing one:

<imgsrc="..."/>// You don't use <img></img>

A div tag can have children, and so you use opening and closing tags:

<div>Childrenhere...</div>

The same applies to React components. If the component has children content, it might look like this:

<Greeting>Hello!</Greeting>
// Notice the position of the / character.

If the component does not have children, you can write it with open/closing tags or just a self-closing tag:

// 2 valid ways<Greeting></Greeting><Greeting/>
// Notice how the / character moves based on whether the element
// is self-closing or not

The following use is invalid:

// Wrong<Greeting><Greeting/>

If you misplace the / character, you will get errors like:

Syntax error: Unterminated JSX contents

14 — Assuming import/export will just work

The import/export feature is an official feature in JavaScript (since 2015). However, it’s the only ES2015 feature that is not yet fully supported in modern browsers and the latest Node.

The popular configuration of a React project uses Webpack and Babel. Both allow the use of this feature and compile it down to something all browsers can understand. You can only use import/export if you have something like Webpack or Babel in your flow.

However, having import/export in your React bundled app does not mean that you can just use them anywhere you want! For example, if you’re also doing server-side rendering through the latest Node, things will not work for you. You will most likely get an “unexpected token” error.

To have Node understand import/export as well (which is something you need if you use them on the front-end and you want to do SSR as well), you will have to run Node itself with a Babel preset (like the env preset) that can transpile them. You can use tools like pm2, nodemon, and babel-watch to do so in development and have Node restart every time you change something.

15 — Not binding handler methods

I saved this one for last because it’s a big one and a very common problem.

You can define class methods in a React component and then use them in the component’s render method. For example:

classGreetingextendsReact.Component{whoIsThis(){console.dir(this);// "this" is the caller of whoIsThis return"World";}render(){return`Hello ${this.whoIsThis()}`;}}ReactDOM.render(<Greeting/>,mountNode);

I used the whoIsThis method inside the render method with this.whoIsThis because inside render, the this keyword refers to the component instance associated with the DOM element that represents the component.

React internally makes sure that “this” inside its class methods refers to the instance. However, JavaScript does not bind the instance automatically when you use a reference to the whoIsThis method.

The console.dir line in whoIsThis will correctly report the component instance because that method was called directly from the render method with an explicit caller (this). You should see the Greeting object in the console when you execute the code above:

However, when you use the same method in a delayed-execution channel, such as an event handler, the caller will no longer be explicit and the console.dir line will not report the component instance.

See the code and output (after clicking) below.

In the code above, React invokes the whoIsThis method when you click on the string, but it will not give you access to the component instance inside of it. This is why you get undefined when we click the string. This is a problem if your class method needs access to things like this.props and this.state. It will simply not work.

There are many solutions for this problem. You can wrap the method in an inline function or use the .bind call to force the method to remember its caller. Both are okay for infrequently-updated components. You can also optimize the bind method by doing it in the constructor of the class instead of in the render method. However, the best solution to this method is to enable the ECMAScript class-fields feature (which is still stage-3) through Babel and just use an arrow function for the handlers:

I completely agree with you. When I started using reactjs I found a lot of issues because, literally, I tried to run before learning how to walk... Currently I still having a lot of things pending to learn or to implement in practice, but I'm really excited about using reactjs :D

Just start JS with JS. I think it is good to learn the old js first, go through the "you don't know javascript" serie of kyle simpson, then you take the ES6 book of Zakas. After that you will be ready for any JS and Node library/framework.

I found it pretty insightful to set up AirBnB linting and learning from what it flags up as issues, esp. since the app might apparently still work correctly with various anti-patterns or misuse without you realising you're doing something wrong.

A decent IDE would have flagged up some of these issues and not necessarily explained what was wrong, but the linter would have picked up pretty much all of these issues and explained exactly what's wrong and common best-practice solutions/alternatives.

However, I don't agree with your suggestion in point 16. I think using auto-biding of JS arrow function class properties may not be such a great idea.
Take a look at this article: medium.com/@charpeni/arrow-functio...