Learn React.

  • React.js FAQ
  • Author: Front-end xiaozhi

FundebugReproduced with authorization, copyright belongs to the original author.

At jsComplete, we manage a Slack account specifically designed to help programming learners. We often get some interesting questions, but most of them are common. I created this resource to help React. Js learners with some of these common problems. It’s a quick way to find solutions to some common problems, rather than trying to find solutions over and over again, and I’m going to keep updating these common problems.

1. The component name must start with a capital letter

The React component name must start with an uppercase letter.

If the component name does not begin with a capital letter, the component usage will be considered a built-in element, such as div or SPAN.

Such as:

class greeting extends React.Component { 
  // ...
}
Copy the code

If you try to render the
, React will ignore the above content and issue the following 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.
Copy the code

The bigger problem here is naming the component button or IMG. React will ignore your components and just render a normal HTML button or IMG tag.

Notice that “My Awesome Button” and the empty HTML Button element just rendered by React are not rendered above. In this case, React doesn’t warn you.

2. Use single quotes instead of back quotes

Use back quotes (…) Create strings with single quotes (‘… ‘) creates different strings.

On most keyboards, you can use the key above the TAB key to enter backquotation (‘) characters.

When you need to include dynamic expressions in a string, create a string using backquotes (no string concatenation is required).

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

Suppose you want a string that always reports the current time:

“Time is…”

// Current time string
const time = new Date().toLocaleTimeString();
// To use ordinary strings (single or double quotes), string concatenation is required:
'Time is ' + time
// When using backquotes, you can use ${} to inject time into a string
`Time is ${time}`
Copy the code

In addition, when backquotes also declare a string, we can create a string that spans multiple lines:

const template = `I
CAN
SPAN
Multiple Lines`;
Copy the code

Regular strings cannot do this.

3. Use the React. PropTypes

The PropTypes object has been removed from React. It used to be used as React.PropTypes, but it can’t be used anymore.

In return, you need to:

  1. npm install prop-types
  2. import PropTypes from 'prop-types'

Then you can use it, as in proptypes.string.

If you use React.PropTypes incorrectly, you get an error message like this:

TypeError: Cannot read property 'string' of undefined
Copy the code

4. The version specified in the user guide is not available

When reading or reading about the code and the examples in the guide, make sure that the version of the library you are using is the same as that in the examples. Using the latest version is generally fine, but if the content is out of date, you may encounter some deprecation issues.

For security, use the trunk version. For example, if you use React 16 in the tutorial, don’t use React 15 yourself.

This is also important for Node.js. If you use older versions of Node, you run into a number of issues. For example, if you’re looking at some tutorial that uses Object.values and you’re using Node 6.x, this method doesn’t exist in that version. You’ll need Node 7.x or later.

5. Confusing functions and classes

Can you see what’s wrong with the code below?

class Numbers extends React.Component {
  const arrayOfNumbers = _.range(1.10);
  // ...
}
Copy the code

The above code is invalid because inside a JavaScript class, variables cannot be arbitrarily defined, only methods and properties defined using the specified syntax.

This is a little confusing, because the {} used in class syntax looks like block-level scope, but it isn’t.

In a component consisting of functions, you can do whatever you want with it:

// Totally Okay:
const Number = (props) = > {
  const arrayOfNumbers = _.range(1.10);
  // ...
};
Copy the code

6. Pass numbers as strings

You can pass a string through the prop property:

<Greeting name="World" />
Copy the code

If you need to pass a value, do not use a string:

// Don't do that<Greeting counter="Seven" />
Copy the code

Instead, use curly braces to pass an actual value:

<Greeting counter={7} />
Copy the code

Using {7} in the Greeting component, this.props. Counter is assigned the number 7 and can be mathematically evaluated. If you pass it as a “7” and then treat it as a number, you may encounter unexpected results.

7. Forgetting that another app is using the same port

To run a Web server, use a host (such as 127.0.0.1) and a port (such as 8080) to make the server listen for requests at a valid HTTP address.

Once it runs successfully, the Web server takes over that port, you can’t let that port be used, that port will be occupied.

If you try to run the same server on another terminal, you will get an error message indicating that the port is occupied, as follows:

Error: listen EADDRINUSE 127.0. 01.:8080
Copy the code

Note that sometimes the Web server may be running in the background or in a separate screen/TMUx session. You can’t see it, but it still occupies the port. To restart the server, you need to “kill” the server that is still running.

To identify processes using a particular port, use commands like ps (and grep about the application), or lsof if you know the port number:

lsof -i :8080
Copy the code

8. Forgetting to create environment variables

Some projects rely on the presence of shell environment variables to start. If you run these projects without the required environment variables, they will try to use undefined values for them and may give you some mysterious errors.

For example, if your project is connected to a database like MongoDB, you might use an environment variable like process.env.mongo_uri to connect to it. This allows projects to be used with different MongoDB instances in different environments.

To run a project connected to MongoDB locally, you must first export the MONGO_URI environment variable. For example, if you are running native MongoDB on port 27017, you need to do this before running the project:

export MONGO_URI="mongodb://localhost:27017/mydb"
Copy the code

You can grep the project source and go to process.env to see what environment variables it needs to run properly.

9. Confuse curly braces {} with parentheses ()

Do not use:

return {
  something();
};
Copy the code

Used like this:

return( something(); ) ;Copy the code

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

Because any

in JSX will be converted to a function call, this problem occurs when any JSX is returned.

This problem is also common in the abbreviated syntax of arrow functions.

Do not use:

const Greeting = () => {
  <div>
    Hello World
  </div>
};
Copy the code

Used like this:

const Greeting = (a)= > (
  <div>
    Hello World
  </div>
);
Copy the code

When you use brackets with arrow functions, you create a new function scope. The abbreviation syntax for arrow functions does not use brackets.

The bugs that may exist after code deployment cannot be known in real time. In order to solve these bugs, I spent a lot of time on log debugging. Incidentally, I recommend a good BUG monitoring tool for youFundebug.

10. Do not wrap objects with parentheses

The curly braces and parentheses problem above can also confuse you when you want to create an arrow function that returns a normal object.

Do not use:

const myAction = (a)= > { type: 'DO_THIS' };
Copy the code

Used like this:

const myAction = (a)= > ({ type: 'DO_THIS'});
Copy the code

You cannot use abbreviation syntax without enclosing the object in parentheses. You’re actually going to define a label for the string.

This is common in the setState method’s updater function because it needs to return an object. If you want to use arrow function syntax, you need to wrap the object in parentheses.

Do not use:

this.setState(prevState= > { answer: 42 });
Copy the code

Used like this:

this.setState(prevState= > ({ answer: 42 }));
Copy the code

11. Improper use of case for API elements and attributes

Use react.component, not React.component. Use componentDidMount instead of componentDidMount. Use ReactDOM, not ReactDOM.

Note the API case required. If you use incorrect capitalization, the resulting error message may not be clear.

When importing from React and react-DOM, make sure you import the correct name and use exactly the same content as you imported. ESLint can help you point out unused content.

This problem is also encountered when dealing with component properties:

<Greeting userName="Max" />// Inside the component, you need to use props. UserName to get the value passed inCopy the code

If you use props.UserName or props.UserName instead of props. Keep an eye out for this, and better yet, configure ESLint, which also addresses these issues.

12. Confusing state objects with instance attributes

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

class Greeting extends React.Component {
  state = {
    name: "World"}; render() {return `Hello The ${this.state.name}`; }}Copy the code

The above code will print “Hello World”.

In addition to state, you can define other local instance properties.

class Greeting extends React.Component {
  user = {
    name: "World"}; render() {return `Hello The ${this.user.name}`; }}Copy the code

The code above also prints “Hello World”.

The state instance property is a special property because React manages it. You can only change it with setState, and when you do React will respond.

However, all other instance attributes defined have no effect on the rendering algorithm. You can change this.user as needed in the example above, and React does not trigger the rendering mechanism in React.

13. Will be confused with </ tag>

Error/character in closing tag. Admittedly, sometimes you can use
, and other times you need .

In HTML, there is something called “self-closing tags” (AKA void tags). These are tags that represent elements that do not have any child nodes. For example, the IMG tag is a self-closing tag:

<img src="..." />// Do not use it<img></img>
Copy the code

Div tags can contain children, so you can use start and end tags:

<div>
  Children here...
</div>
Copy the code

The same applies to the Reac T component if the component has child elements as follows:

<Greeting>Hello!</Greeting>// Note the position of the/characterCopy the code

If the component has no child elements, it can be written with a start/end tag, or with a self-closing tag:

// Two ways<Greeting></Greeting>
<Greeting />
Copy the code

It is illegal to:

/ / error<Greeting><Greeting />  
Copy the code

If you misplace the/character, you will receive the following error:

Syntax error: Unterminated JSX contents
Copy the code

14. Assume that import/export works

The import/export feature is an official feature in JavaScript (since 2015). It is only an ES2015 feature and is not fully supported in popular browsers or the latest versions of Node.

Popular configurations for React projects use Webpack and Babel. Both allow you to use this feature and compile it into something that all browsers can understand. Import /export can only be used if there is a translation tool such as Webpack or Babel in the workflow.

However, just because you import/export in the React package application doesn’t mean you can use them freely! For example, if you’re still rendering server-side through the latest Node, it won’t work, and you’ll probably get an “unexpected token” error.

For Node to understand import/export (which you need to know if you use them in the front end and want to do SSR rendering too), you need a Babel preset that can be compiled (like _env_ preset) to run in Node. You can do this at development time using tools like PM2_, _nodemon, and _babel-watch_, and restart Node every time you make a change.

15. Unbound handler methods

I’ll save this for last, because this is a big question, a very common question.

You can define class methods in the React component and then use them in the render method of the component. Such as:

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

I call the whoIsThis method in render as this.whoIsThis, because in render the this keyword refers to the component instance associated with the DOM element representing the component.

Internal React ensures that “this” in its class method points to the instance. However, JavaScript does not automatically bind instances when you use a reference to the whoIsThis method.

Console. dir in the whoIsThis method correctly tells us the current component instance, because the method is called directly from the Render method using the explicit caller (this). When you execute the code above, you see the Greeting object in the console:

However, when the same method is executed in a deferred execution channel, such as event handling, the calling object is no longer explicit and console.dir does not print the current component instance.

In the code above, React calls the whoIsThis method when you click on the string, but it doesn’t give you access to the component instance. That’s why we get undefined when we click on the string. If class methods need to access properties like this.props and this.state, this can be a problem because it simply won’t work.

There are many solutions to this problem. You can wrap methods in inline functions, or use.bind to change the this reference. For components that are not updated frequently, either is fine.

You can also optimize the Bind method by executing it in the class constructor instead of the Render method. However, the best solution for this approach is to use the ECMAScript class field I (currently stage-3) via Babel, so that the handler can simply use the arrow function:

class Greeting extends React.Component {
  whoIsThis = (a)= > {
    console.dir(this);
  }
  render() {
    return (
     <div onClick={this.whoIsThis}>
        Hello World
      </div>); }}Copy the code

This will perform as expected:

The original:React.js Commonly Faced Problems