1 The component name must start with a capital letter

React Component names must start with a capital letter. If the component name does not start with a capital letter, component usage will be considered a built-in element, such as div or SPAN. For example:

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

A warning is given if you try to render

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 that the component is named button or IMG. React will ignore your component and just render a plain Htmlbutton or IMG tag.

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 // Can be used when backquotes are usedThe ${}Injects the Time 'Time is' into the string${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:

npm install prop-types
import PropTypes from 'prop-types'
Copy the code

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
  1. When reading or reading about the code and using the examples in the guide, make sure you use the same version of the library as 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:

// Do not do this <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.0.1: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

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 anything 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 = () => (
  <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, HERE I recommend a good BUG monitoring tool Fundebug.

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 = () => { type: 'DO_THIS' };
Copy the code

Used like this:

const myAction = () => ({ 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" />
Copy the code

// Inside the component, you need to use props.UserName to get the value passed in. If you don’t use 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 ${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 ${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="..." />
Copy the code

The div tag can contain children, so you can use the start and end tags: ‘

Children here…

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 ${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 = () => {
    console.dir(this);
  }
  render() {
    return( <div onClick={this.whoIsThis}> Hello World </div> ); }}Copy the code

This will perform as expected: