@ -104,12 +104,12 @@ If you can’t use `npm` yet, we provide pre-built browser builds for your conve
With this change, we’re deprecating `.getDOMNode()` and replacing it with `ReactDOM.findDOMNode` (see below). If your components are currently using `.getDOMNode()`, they will continue to work with a warning until 0.15.
With this change, we’re deprecating `.getDOMNode()` and replacing it with `ReactDOM.findDOMNode` (see below). If your components are currently using `.getDOMNode()`, they will continue to work with a warning until 0.15.
- #### Stateless functional components
- #### Stateless function components
In idiomatic React code, most of the components you write will be stateless, simply composing other components. We’re introducing a new, simpler syntax for these components where you can take `props` as an argument and return the element you want to render:
In idiomatic React code, most of the components you write will be stateless, simply composing other components. We’re introducing a new, simpler syntax for these components where you can take `props` as an argument and return the element you want to render:
```js
```js
// A functional component using an ES2015 (ES6) arrow function:
// A function component using an ES2015 (ES6) arrow function:
var Aquarium = (props) => {
var Aquarium = (props) => {
var fish = getFish(props.species);
var fish = getFish(props.species);
return <Tank>{fish}</Tank>;
return <Tank>{fish}</Tank>;
@ -125,7 +125,7 @@ If you can’t use `npm` yet, we provide pre-built browser builds for your conve
// Then use: <Aquariumspecies="rainbowfish"/>
// Then use: <Aquariumspecies="rainbowfish"/>
```
```
These components behave just like a React class with only a `render` method defined. Since no component instance is created for a functional component, any `ref` added to one will evaluate to `null`. Functional components do not have lifecycle methods, but you can set `.propTypes` and `.defaultProps` as properties on the function.
These components behave just like a React class with only a `render` method defined. Since no component instance is created for a function component, any `ref` added to one will evaluate to `null`. Function components do not have lifecycle methods, but you can set `.propTypes` and `.defaultProps` as properties on the function.
This pattern is designed to encourage the creation of these simple components that should comprise large portions of your apps. In the future, we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations.
This pattern is designed to encourage the creation of these simple components that should comprise large portions of your apps. In the future, we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations.
@ -294,9 +294,9 @@ class Button extends React.Component {
}
}
```
```
When a component is defined as a class, it is a little bit more powerful than a functional component. It can store some local state and perform custom logic when the corresponding DOM node is created or destroyed.
When a component is defined as a class, it is a little bit more powerful than a function component. It can store some local state and perform custom logic when the corresponding DOM node is created or destroyed.
A functional component is less powerful but is simpler, and acts like a class component with just a single `render()` method. Unless you need features available only in a class, we encourage you to use functional components instead.
A function component is less powerful but is simpler, and acts like a class component with just a single `render()` method. Unless you need features available only in a class, we encourage you to use function components instead.
**However, whether functions or classes, fundamentally they are all components to React. They take the props as their input, and return the elements as their output.**
**However, whether functions or classes, fundamentally they are all components to React. They take the props as their input, and return the elements as their output.**
@ -370,7 +370,7 @@ When a component receives some props as an input, it is because a particular par
An *instance* is what you refer to as `this` in the component class you write. It is useful for [storing local state and reacting to the lifecycle events](/docs/component-api.html).
An *instance* is what you refer to as `this` in the component class you write. It is useful for [storing local state and reacting to the lifecycle events](/docs/component-api.html).
Functional components don’t have instances at all. Class components have instances, but you never need to create a component instance directly—React takes care of this.
Function components don’t have instances at all. Class components have instances, but you never need to create a component instance directly—React takes care of this.
Finally, to create elements, use [`React.createElement()`](/docs/top-level-api.html#react.createelement), [JSX](/docs/jsx-in-depth.html), or an [element factory helper](/docs/top-level-api.html#react.createfactory). Don’t write elements as plain objects in the real code—just know that they are plain objects under the hood.
Finally, to create elements, use [`React.createElement()`](/docs/top-level-api.html#react.createelement), [JSX](/docs/jsx-in-depth.html), or an [element factory helper](/docs/top-level-api.html#react.createfactory). Don’t write elements as plain objects in the real code—just know that they are plain objects under the hood.
@ -71,7 +71,7 @@ If you can’t use `npm` yet, we provide pre-built browser builds for your conve
<small>[@sophiebits](https://github.com/sophiebits) in [#5451](https://github.com/facebook/react/pull/5451)</small>
<small>[@sophiebits](https://github.com/sophiebits) in [#5451](https://github.com/facebook/react/pull/5451)</small>
- #### Functional components can now return `null` too
- #### Function components can now return `null` too
We added support for [defining stateless components as functions](/blog/2015/09/10/react-v0.14-rc1.html#stateless-function-components) in React 0.14. However, React 0.14 still allowed you to define a class component without extending `React.Component` or using `React.createClass()`, so [we couldn’t reliably tell if your component is a function or a class](https://github.com/facebook/react/issues/5355), and did not allow returning `null` from it. This issue is solved in React 15, and you can now return `null` from any component, whether it is a class or a function.
We added support for [defining stateless components as functions](/blog/2015/09/10/react-v0.14-rc1.html#stateless-function-components) in React 0.14. However, React 0.14 still allowed you to define a class component without extending `React.Component` or using `React.createClass()`, so [we couldn’t reliably tell if your component is a function or a class](https://github.com/facebook/react/issues/5355), and did not allow returning `null` from it. This issue is solved in React 15, and you can now return `null` from any component, whether it is a class or a function.
@ -373,7 +373,7 @@ function withSubscription(WrappedComponent) {
});
});
}
}
// Optional change: convert CommentList to a functional component
// Optional change: convert CommentList to a function component
// because it doesn't use lifecycle hooks or state.
// because it doesn't use lifecycle hooks or state.
function CommentList(props) {
function CommentList(props) {
var comments = props.comments;
var comments = props.comments;
@ -467,7 +467,7 @@ Props keep component dependencies explicit, easy to replace, and enforceable wit
> **Note:**
> **Note:**
>
>
> Defining components as functions is not required. There is also nothing wrong with using lifecycle hooks and state—they are first-class React features. We use functional components in this example because they are easier to read and we didn’t need those extra features, but classes would work just as fine.
> Defining components as functions is not required. There is also nothing wrong with using lifecycle hooks and state—they are first-class React features. We use function components in this example because they are easier to read and we didn’t need those extra features, but classes would work just as fine.
@ -69,7 +69,7 @@ You may also consider using [Flow](https://flow.org/) to statically type check y
When React was initially released, there was no idiomatic way to create classes in JavaScript, so we provided our own: `React.createClass`.
When React was initially released, there was no idiomatic way to create classes in JavaScript, so we provided our own: `React.createClass`.
Later, classes were added to the language as part of ES2015, so we added the ability to create React components using JavaScript classes. **Along with functional components, JavaScript classes are now the [preferred way to create components in React](/docs/components-and-props.html#functional-and-class-components).**
Later, classes were added to the language as part of ES2015, so we added the ability to create React components using JavaScript classes. **Along with function components, JavaScript classes are now the [preferred way to create components in React](/docs/components-and-props.html#functional-and-class-components).**
For your existing `createClass` components, we recommend that you migrate them to JavaScript classes. However, if you have components that rely on mixins, converting to classes may not be immediately feasible. If so, `create-react-class` is available on npm as a drop-in replacement:
For your existing `createClass` components, we recommend that you migrate them to JavaScript classes. However, if you have components that rely on mixins, converting to classes may not be immediately feasible. If so, `create-react-class` is available on npm as a drop-in replacement:
@ -41,7 +41,7 @@ Version 16.3 adds a new option for managing refs that offers the convenience of
Generally, React components are declarative, but sometimes imperative access to the component instances and the underlying DOM nodes is necessary. This is common for use cases like managing focus, selection, or animations. React provides [refs](/docs/refs-and-the-dom.html) as a way to solve this problem. However, component encapsulation poses some challenges with refs.
Generally, React components are declarative, but sometimes imperative access to the component instances and the underlying DOM nodes is necessary. This is common for use cases like managing focus, selection, or animations. React provides [refs](/docs/refs-and-the-dom.html) as a way to solve this problem. However, component encapsulation poses some challenges with refs.
For example, if you replace a `<button>` with a custom `<FancyButton>` component, the `ref` attribute on it will start pointing at the wrapper component instead of the DOM node (and would be `null` for functional components). While this is desirable for "application-level" components like `FeedStory` or `Comment` that need to be encapsulated, it can be annoying for "leaf" components such as `FancyButton` or `MyTextInput` that are typically used like their DOM counterparts, and might need to expose their DOM nodes.
For example, if you replace a `<button>` with a custom `<FancyButton>` component, the `ref` attribute on it will start pointing at the wrapper component instead of the DOM node (and would be `null` for function components). While this is desirable for "application-level" components like `FeedStory` or `Comment` that need to be encapsulated, it can be annoying for "leaf" components such as `FancyButton` or `MyTextInput` that are typically used like their DOM counterparts, and might need to expose their DOM nodes.
Ref forwarding is a new opt-in feature that lets some components take a `ref` they receive, and pass it further down (in other words, "forward" it) to a child. In the example below, `FancyButton` forwards its ref to a DOM `button` that it renders:
Ref forwarding is a new opt-in feature that lets some components take a `ref` they receive, and pass it further down (in other words, "forward" it) to a child. In the example below, `FancyButton` forwards its ref to a DOM `button` that it renders:
@ -104,7 +104,7 @@ This design is fundamentally flawed, but it's also an easy mistake to make. ([I'
### Recommendation: Fully controlled component
### Recommendation: Fully controlled component
One way to avoid the problems mentioned above is to remove state from our component entirely. If the email address only exists as a prop, then we don't have to worry about conflicts with state. We could even convert `EmailInput` to a lighter-weight functional component:
One way to avoid the problems mentioned above is to remove state from our component entirely. If the email address only exists as a prop, then we don't have to worry about conflicts with state. We could even convert `EmailInput` to a lighter-weight function component:
@ -20,7 +20,7 @@ Components let you split the UI into independent, reusable pieces, and think abo
Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called "props") and return React elements describing what should appear on the screen.
Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called "props") and return React elements describing what should appear on the screen.
## Functional and Class Components
## Function and Class Components
The simplest way to define a component is to write a JavaScript function:
The simplest way to define a component is to write a JavaScript function:
@ -30,7 +30,7 @@ function Welcome(props) {
}
}
```
```
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.
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 "function components" because they are literally JavaScript functions.
You can also use an [ES6 class](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes) to define a component:
You can also use an [ES6 class](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes) to define a component:
@ -44,7 +44,7 @@ class Welcome extends React.Component {
The above two components are equivalent from React's point of view.
The above two components are equivalent from React's point of view.
Classes have some additional features that we will discuss in the [next sections](/docs/state-and-lifecycle.html). Until then, we will use functional components for their conciseness.
Classes have some additional features that we will discuss in the [next sections](/docs/state-and-lifecycle.html). Until then, we will use function components for their conciseness.
## Rendering a Component
## Rendering a Component
@ -237,7 +237,7 @@ Extracting components might seem like grunt work at first, but having a palette
## Props are Read-Only
## Props are Read-Only
Whether you declare a component [as a function or a class](#functional-and-class-components), it must never modify its own props. Consider this `sum` function:
Whether you declare a component [as a function or a class](#function-and-class-components), it must never modify its own props. Consider this `sum` function:
@ -33,7 +33,7 @@ Here is a step-by-step explanation of what happens in the above example:
>Note
>Note
>
>
>The second `ref` argument only exists when you define a component with `React.forwardRef` call. Regular functional or class components don't receive the `ref` argument, and ref is not available in props either.
>The second `ref` argument only exists when you define a component with `React.forwardRef` call. Regular function or class components don't receive the `ref` argument, and ref is not available in props either.
>
>
>Ref forwarding is not limited to DOM components. You can forward refs to class component instances, too.
>Ref forwarding is not limited to DOM components. You can forward refs to class component instances, too.
There are a few problems with this. One is that the input component cannot be reused separately from the enhanced component. More crucially, if you apply another HOC to `EnhancedComponent` that *also* mutates `componentWillReceiveProps`, the first HOC's functionality will be overridden! This HOC also won't work with functional components, which do not have lifecycle methods.
There are a few problems with this. One is that the input component cannot be reused separately from the enhanced component. More crucially, if you apply another HOC to `EnhancedComponent` that *also* mutates `componentWillReceiveProps`, the first HOC's functionality will be overridden! This HOC also won't work with function components, which do not have lifecycle methods.
Mutating HOCs are a leaky abstraction—the consumer must know how they are implemented in order to avoid conflicts with other HOCs.
Mutating HOCs are a leaky abstraction—the consumer must know how they are implemented in order to avoid conflicts with other HOCs.
@ -211,7 +211,7 @@ function logProps(WrappedComponent) {
}
}
```
```
This HOC has the same functionality as the mutating version while avoiding the potential for clashes. It works equally well with class and functional components. And because it's a pure function, it's composable with other HOCs, or even with itself.
This HOC has the same functionality as the mutating version while avoiding the potential for clashes. It works equally well with class and function components. And because it's a pure function, it's composable with other HOCs, or even with itself.
You may have noticed similarities between HOCs and a pattern called **container components**. Container components are part of a strategy of separating responsibility between high-level and low-level concerns. Containers manage things like subscriptions and state, and pass props to components that handle things like rendering UI. HOCs use containers as part of their implementation. You can think of HOCs as parameterized container component definitions.
You may have noticed similarities between HOCs and a pattern called **container components**. Container components are part of a strategy of separating responsibility between high-level and low-level concerns. Containers manage things like subscriptions and state, and pass props to components that handle things like rendering UI. HOCs use containers as part of their implementation. You can think of HOCs as parameterized container component definitions.
The main difference after refactoring from `mountHost()` is that we now keep `this.node` and `this.renderedChildren` associated with the internal DOM component instance. We will also use them for applying non-destructive updates in the future.
The main difference after refactoring from `mountHost()` is that we now keep `this.node` and `this.renderedChildren` associated with the internal DOM component instance. We will also use them for applying non-destructive updates in the future.
As a result, each internal instance, composite or host, now points to its child internal instances. To help visualize this, if a functional`<App>` component renders a `<Button>` class component, and `Button` class renders a `<div>`, the internal instance tree would look like this:
As a result, each internal instance, composite or host, now points to its child internal instances. To help visualize this, if a function `<App>` component renders a `<Button>` class component, and `Button` class renders a `<div>`, the internal instance tree would look like this:
@ -152,11 +152,11 @@ If `contextTypes` is defined within a component, the following [lifecycle method
>
>
> As of React 16, `componentDidUpdate` no longer receives `prevContext`.
> As of React 16, `componentDidUpdate` no longer receives `prevContext`.
### Referencing Context in Stateless Functional Components
### Referencing Context in Stateless Function Components
> This section documents a legacy API. See the [new API](/docs/context.html).
> This section documents a legacy API. See the [new API](/docs/context.html).
Stateless functional components are also able to reference `context` if `contextTypes` is defined as a property of the function. The following code shows a `Button` component written as a stateless functional component.
Stateless function components are also able to reference `context` if `contextTypes` is defined as a property of the function. The following code shows a `Button` component written as a stateless function component.
@ -99,7 +99,7 @@ When a component renders to `null` or `false`, `findDOMNode` returns `null`. Whe
>
>
> `findDOMNode` only works on mounted components (that is, components that have been placed in the DOM). If you try to call this on a component that has not been mounted yet (like calling `findDOMNode()` in `render()` on a component that has yet to be created) an exception will be thrown.
> `findDOMNode` only works on mounted components (that is, components that have been placed in the DOM). If you try to call this on a component that has not been mounted yet (like calling `findDOMNode()` in `render()` on a component that has yet to be created) an exception will be thrown.
>
>
> `findDOMNode` cannot be used on functional components.
> `findDOMNode` cannot be used on function components.
@ -142,7 +142,7 @@ Unmount the in-memory tree, triggering the appropriate lifecycle events.
testRenderer.getInstance()
testRenderer.getInstance()
```
```
Return the instance corresponding to the root element, if available. This will not work if the root element is a functional component because they don't have instances.
Return the instance corresponding to the root element, if available. This will not work if the root element is a function component because they don't have instances.
### `testRenderer.root`
### `testRenderer.root`
@ -206,7 +206,7 @@ Find all descendant test instances with the provided `props`.
testInstance.instance
testInstance.instance
```
```
The component instance corresponding to this test instance. It is only available for class components, as functional components don't have instances. It matches the `this` value inside the given component.
The component instance corresponding to this test instance. It is only available for class components, as function components don't have instances. It matches the `this` value inside the given component.
@ -63,7 +63,7 @@ The value of the ref differs depending on the type of the node:
- When the `ref` attribute is used on an HTML element, the `ref` created in the constructor with `React.createRef()` receives the underlying DOM element as its `current` property.
- When the `ref` attribute is used on an HTML element, the `ref` created in the constructor with `React.createRef()` receives the underlying DOM element as its `current` property.
- When the `ref` attribute is used on a custom class component, the `ref` object receives the mounted instance of the component as its `current`.
- When the `ref` attribute is used on a custom class component, the `ref` object receives the mounted instance of the component as its `current`.
- **You may not use the `ref` attribute on functional components** because they don't have instances.
- **You may not use the `ref` attribute on function components** because they don't have instances.
The examples below demonstrate the differences.
The examples below demonstrate the differences.
@ -138,9 +138,9 @@ class CustomTextInput extends React.Component {
}
}
```
```
#### Refs and Functional Components
#### Refs and Function Components
**You may not use the `ref` attribute on functional components** because they don't have instances:
**You may not use the `ref` attribute on function components** because they don't have instances:
```javascript{1,8,13}
```javascript{1,8,13}
function MyFunctionalComponent() {
function MyFunctionalComponent() {
@ -163,7 +163,7 @@ class Parent extends React.Component {
You should convert the component to a class if you need a ref to it, just like you do when you need lifecycle methods or state.
You should convert the component to a class if you need a ref to it, just like you do when you need lifecycle methods or state.
You can, however, **use the `ref` attribute inside a functional component** as long as you refer to a DOM element or a class component:
You can, however, **use the `ref` attribute inside a function component** as long as you refer to a DOM element or a class component:
```javascript{2,3,6,13}
```javascript{2,3,6,13}
function CustomTextInput(props) {
function CustomTextInput(props) {
@ -193,7 +193,7 @@ function CustomTextInput(props) {
In rare cases, you might want to have access to a child's DOM node from a parent component. This is generally not recommended because it breaks component encapsulation, but it can occasionally be useful for triggering focus or measuring the size or position of a child DOM node.
In rare cases, you might want to have access to a child's DOM node from a parent component. This is generally not recommended because it breaks component encapsulation, but it can occasionally be useful for triggering focus or measuring the size or position of a child DOM node.
While you could [add a ref to the child component](#adding-a-ref-to-a-class-component), this is not an ideal solution, as you would only get a component instance rather than a DOM node. Additionally, this wouldn't work with functional components.
While you could [add a ref to the child component](#adding-a-ref-to-a-class-component), this is not an ideal solution, as you would only get a component instance rather than a DOM node. Additionally, this wouldn't work with function components.
If you use React 16.3 or higher, we recommend to use [ref forwarding](/docs/forwarding-refs.html) for these cases. **Ref forwarding lets components opt into exposing any child component's ref as their own**. You can find a detailed example of how to expose a child's DOM node to a parent component [in the ref forwarding documentation](/docs/forwarding-refs.html#forwarding-refs-to-dom-components).
If you use React 16.3 or higher, we recommend to use [ref forwarding](/docs/forwarding-refs.html) for these cases. **Ref forwarding lets components opt into exposing any child component's ref as their own**. You can find a detailed example of how to expose a child's DOM node to a parent component [in the ref forwarding documentation](/docs/forwarding-refs.html#forwarding-refs-to-dom-components).
@ -575,11 +575,11 @@ The main benefit of immutability is that it helps you build _pure components_ in
You can learn more about `shouldComponentUpdate()` and how you can build *pure components* by reading [Optimizing Performance](/docs/optimizing-performance.html#examples).
You can learn more about `shouldComponentUpdate()` and how you can build *pure components* by reading [Optimizing Performance](/docs/optimizing-performance.html#examples).
### Functional Components
### Function Components
We'll now change the Square to be a **functional component**.
We'll now change the Square to be a **function component**.
In React, **functional components** are a simpler way to write components that only contain a `render` method and don't have their own state. Instead of defining a class which extends `React.Component`, we can write a function that takes `props` as input and returns what should be rendered. Functional components are less tedious to write than classes, and many components can be expressed this way.
In React, **function components** are a simpler way to write components that only contain a `render` method and don't have their own state. Instead of defining a class which extends `React.Component`, we can write a function that takes `props` as input and returns what should be rendered. Function components are less tedious to write than classes, and many components can be expressed this way.
Replace the Square class with this function:
Replace the Square class with this function:
@ -599,7 +599,7 @@ We have changed `this.props` to `props` both times it appears.
>Note
>Note
>
>
>When we modified the Square to be a functional component, we also changed `onClick={() => this.props.onClick()}` to a shorter `onClick={props.onClick}` (note the lack of parentheses on *both* sides). In a class, we used an arrow function to access the correct `this` value, but in a functional component we don't need to worry about `this`.
>When we modified the Square to be a function component, we also changed `onClick={() => this.props.onClick()}` to a shorter `onClick={props.onClick}` (note the lack of parentheses on *both* sides). In a class, we used an arrow function to access the correct `this` value, but in a function component we don't need to worry about `this`.