- It's a good practice to wrap components definitions with parenthesis.
const element = (
<h1>
Hello, {formatName(user)}!
</h1>
);
- Properties naming
Since JSX is closer to JavaScript than to HTML, React DOM uses camelCase property naming convention instead of HTML attribute names. For example, class becomes className in JSX, and tabindex becomes tabIndex.
- Handling events
Handling events with React elements is very similar to handling events on DOM elements. There are some syntactic differences:
- React events are named using camelCase, rather than lowercase.
- With JSX you pass a function as the event handler, rather than a string.
- Another difference is that you cannot return
false
to prevent default behavior in React. You must callpreventDefault
explicitly. You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default. If you forget to bindthis.handleClick
and pass it toonClick
, this will be undefined when the function is actually called.
This binding can be done in different ways. On way is to bind the this
on the constructor. Example:
constructor(props){
this.handleClick = this.handleClick.bind(this);
}
- Preventing component from rendering
In rare cases you might want a component to hide itself even though it was rendered by another component. To do this return null instead of its render output. Returning null from a component’s render method does not affect the firing of the component’s lifecycle methods. For instance componentDidUpdate will still be called.
Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called “props”) and return React elements describing what should appear on the screen.
There are two types of components: functional and Class components.
- functional
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
This function is a valid React component because it accepts a single “props” (which stands for properties) object argument with data and returns a React element. We call such components “functional” because they are literally JavaScript functions.
- Class
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
NOTE:
Always start component names with a capital letter.
- Props
Props are Read-Only.
All React components must act like pure functions with respect to their props. Of course, application UIs are dynamic and change over time. In the next section, we will introduce a new concept of “state”. State allows React components to change their output over time in response to user actions, network responses, and anything else, without violating this rule.
- State
States can change.
state
is similar toprops
, but it is private and fully controlled by the component.
Local state is a feature available only to classes. Lifecycle hooks are a feature available only to classes.
There are three things you should know about setState()
.
- Do not modify state directly. Instead, use
setState()
.- The only place where you can assign this.state is the constructor.
- State updates may be asynchronous.
- Because
this.props
andthis.state
may be updated asynchronously, you should not rely on their values for calculating the next state. - To fix it, use a second form of
setState()
that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument.
- Because
state
updates are merged.- The merging is shallow.
This is commonly called a “top-down” or “unidirectional” data flow. Any state is always owned by some specific component, and any data or UI derived from that state can only affect components “below” them in the tree.
In React, sharing state is accomplished by moving it up to the closest common ancestor of the components that need it. This is called “lifting state up”. There should be a single “source of truth” for any data that changes in a React application. Usually, the state is first added to the component that needs it for rendering. Then, if other components also need it, you can lift it up to their closest common ancestor. Instead of trying to sync the state between different components, you should rely on the top-down data flow.