diff --git a/.gitignore b/.gitignore
index d1bde99ce..420e5874f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,5 @@
.idea
node_modules
public
-yarn-error.log
\ No newline at end of file
+yarn-error.log
+.vscode
\ No newline at end of file
diff --git a/content/blog/2019-02-23-is-react-translated-yet.md b/content/blog/2019-02-23-is-react-translated-yet.md
index 78bc49b6e..3ac56a5a4 100644
--- a/content/blog/2019-02-23-is-react-translated-yet.md
+++ b/content/blog/2019-02-23-is-react-translated-yet.md
@@ -43,7 +43,7 @@ We started of with an initial trial period of three languages: Spanish, Japanese
After the trial period, we were ready to accept more languages. I created [a script](https://github.com/reactjs/reactjs.org-translation/blob/master/scripts/create.js) to automate the creation of the new language repo, and a site, [Is React Translated Yet?](https://isreacttranslatedyet.com), to track progress on the different translations. We started *10* new translations on our first day alone!
-Because of the automation, the rest of the maintance went mostly smoothly. We eventually created a [Slack channel](https://rt-slack-invite.herokuapp.com) to make it easier for translators to share information, and I released a guide solidifying the [responsibilities of maintainers](https://github.com/reactjs/reactjs.org-translation/blob/master/maintainer-guide.md). Allowing translators to talk with each other was a great boon -- for example, the Arabic, Persian, and Hebrew translations were able to talk to each other in order to get [right-to-left text](https://en.wikipedia.org/wiki/Right-to-left) working!
+Because of the automation, the rest of the maintenance went mostly smoothly. We eventually created a [Slack channel](https://rt-slack-invite.herokuapp.com) to make it easier for translators to share information, and I released a guide solidifying the [responsibilities of maintainers](https://github.com/reactjs/reactjs.org-translation/blob/master/maintainer-guide.md). Allowing translators to talk with each other was a great boon -- for example, the Arabic, Persian, and Hebrew translations were able to talk to each other in order to get [right-to-left text](https://en.wikipedia.org/wiki/Right-to-left) working!
## The Bot {#the-bot}
diff --git a/content/community/conferences.md b/content/community/conferences.md
index 89ed871d0..ea8613c78 100644
--- a/content/community/conferences.md
+++ b/content/community/conferences.md
@@ -57,6 +57,11 @@ July 15-21, 2019. New York City, USA
[Website](https://reactweek.nyc) - [Twitter](https://twitter.com/ReactWeek)
+### React Rally 2019
+August 22-23, 2019. Salt Lake City, USA.
+
+[Website](https://www.reactrally.com/) - [Twitter](https://twitter.com/ReactRally) - [Instagram](https://www.instagram.com/reactrally/)
+
### ComponentsConf 2019 {#componentsconf-2019}
September 6, 2019 in Melbourne, Australia
[Website](https://www.componentsconf.com.au/) - [Twitter](https://twitter.com/componentsconf)
@@ -76,6 +81,11 @@ September 26-28, 2019 in Goa, India
[Website](https://www.reactindia.io/) - [Twitter](https://twitter.com/react_india) - [Facebook](https://www.facebook.com/ReactJSIndia)
+### React Alicante 2019 {#react-alicante-2019}
+September 26-28, 2019 in Alicante, Spain
+
+[Website](http://reactalicante.es/) - [Twitter](https://twitter.com/reactalicante) - [Facebook](https://www.facebook.com/ReactAlicante)
+
## Past Conferences {#past-conferences}
### React.js Conf 2015 {#reactjs-conf-2015}
diff --git a/content/docs/addons-test-utils.md b/content/docs/addons-test-utils.md
index a6e06e1be..6cf2af081 100644
--- a/content/docs/addons-test-utils.md
+++ b/content/docs/addons-test-utils.md
@@ -53,7 +53,7 @@ To prepare a component for assertions, wrap the code rendering it and performing
For example, let's say we have this `Counter` component:
```js
-class App extends React.Component {
+class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {count: 0};
diff --git a/content/docs/hooks-custom.md b/content/docs/hooks-custom.md
index ac9dad6da..a252ac3f3 100644
--- a/content/docs/hooks-custom.md
+++ b/content/docs/hooks-custom.md
@@ -18,11 +18,11 @@ import React, { useState, useEffect } from 'react';
function FriendStatus(props) {
const [isOnline, setIsOnline] = useState(null);
- function handleStatusChange(status) {
- setIsOnline(status.isOnline);
- }
-
useEffect(() => {
+ function handleStatusChange(status) {
+ setIsOnline(status.isOnline);
+ }
+
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
@@ -44,11 +44,11 @@ import React, { useState, useEffect } from 'react';
function FriendListItem(props) {
const [isOnline, setIsOnline] = useState(null);
- function handleStatusChange(status) {
- setIsOnline(status.isOnline);
- }
-
useEffect(() => {
+ function handleStatusChange(status) {
+ setIsOnline(status.isOnline);
+ }
+
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
@@ -79,11 +79,11 @@ import React, { useState, useEffect } from 'react';
function useFriendStatus(friendID) {
const [isOnline, setIsOnline] = useState(null);
- function handleStatusChange(status) {
- setIsOnline(status.isOnline);
- }
-
useEffect(() => {
+ function handleStatusChange(status) {
+ setIsOnline(status.isOnline);
+ }
+
ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
diff --git a/content/docs/hooks-effect.md b/content/docs/hooks-effect.md
index 64b32476e..73d6a3d2c 100644
--- a/content/docs/hooks-effect.md
+++ b/content/docs/hooks-effect.md
@@ -3,7 +3,7 @@ id: hooks-state
title: Using the Effect Hook
permalink: docs/hooks-effect.html
next: hooks-rules.html
-prev: hooks-intro.html
+prev: hooks-state.html
---
*Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class.
@@ -198,17 +198,17 @@ Let's see how we could write this component with Hooks.
You might be thinking that we'd need a separate effect to perform the cleanup. But code for adding and removing a subscription is so tightly related that `useEffect` is designed to keep it together. If your effect returns a function, React will run it when it is time to clean up:
-```js{10-16}
+```js{6-16}
import React, { useState, useEffect } from 'react';
function FriendStatus(props) {
const [isOnline, setIsOnline] = useState(null);
- function handleStatusChange(status) {
- setIsOnline(status.isOnline);
- }
-
useEffect(() => {
+ function handleStatusChange(status) {
+ setIsOnline(status.isOnline);
+ }
+
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
// Specify how to clean up after this effect:
return function cleanup() {
@@ -237,6 +237,10 @@ We've learned that `useEffect` lets us express different kinds of side effects a
```js
useEffect(() => {
+ function handleStatusChange(status) {
+ setIsOnline(status.isOnline);
+ }
+
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
@@ -316,15 +320,15 @@ function FriendStatusWithCounter(props) {
const [isOnline, setIsOnline] = useState(null);
useEffect(() => {
+ function handleStatusChange(status) {
+ setIsOnline(status.isOnline);
+ }
+
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
-
- function handleStatusChange(status) {
- setIsOnline(status.isOnline);
- }
// ...
}
```
@@ -394,6 +398,7 @@ Now consider the version of this component that uses Hooks:
function FriendStatus(props) {
// ...
useEffect(() => {
+ // ...
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
@@ -449,8 +454,12 @@ When we render with `count` updated to `6`, React will compare the items in the
This also works for effects that have a cleanup phase:
-```js{6}
+```js{10}
useEffect(() => {
+ function handleStatusChange(status) {
+ setIsOnline(status.isOnline);
+ }
+
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
@@ -462,9 +471,13 @@ In the future, the second argument might get added automatically by a build-time
>Note
>
->If you use this optimization, make sure the array includes **any values from the outer scope that change over time and that are used by the effect**. Otherwise, your code will reference stale values from previous renders. We'll also discuss other optimization options in the [Hooks API reference](/docs/hooks-reference.html).
+>If you use this optimization, make sure the array includes **all values from the component scope (such as props and state) that change over time and that are used by the effect**. Otherwise, your code will reference stale values from previous renders. Learn more about [how to deal with functions](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) and [what to do when the array changes too often](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often).
+>
+>If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array (`[]`) as a second argument. This tells React that your effect doesn't depend on *any* values from props or state, so it never needs to re-run. This isn't handled as a special case -- it follows directly from how the inputs array always works.
+>
+>If you pass an empty array (`[]`), the props and state inside the effect will always have their initial values. While passing `[]` as the second argument is closer to the familiar `componentDidMount` and `componentWillUnmount` mental model, there are usually [better](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) [solutions](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often) to avoid re-running effects too often. Also, don't forget that React defers running `useEffect` until after the browser has painted, so doing extra work is less of a problem.
>
->If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array (`[]`) as a second argument. This tells React that your effect doesn't depend on *any* values from props or state, so it never needs to re-run. This isn't handled as a special case -- it follows directly from how the inputs array always works. While passing `[]` is closer to the familiar `componentDidMount` and `componentWillUnmount` mental model, we suggest not making it a habit because it often leads to bugs, [as discussed above](#explanation-why-effects-run-on-each-update). Don't forget that React defers running `useEffect` until after the browser has painted, so doing extra work is less of a problem.
+>We recommend using the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) rule as part of our [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix.
## Next Steps {#next-steps}
diff --git a/content/docs/hooks-faq.md b/content/docs/hooks-faq.md
index b3b99de90..7d2953293 100644
--- a/content/docs/hooks-faq.md
+++ b/content/docs/hooks-faq.md
@@ -32,16 +32,21 @@ This page answers some of the frequently asked questions about [Hooks](/docs/hoo
* [What exactly do the lint rules enforce?](#what-exactly-do-the-lint-rules-enforce)
* **[From Classes to Hooks](#from-classes-to-hooks)**
* [How do lifecycle methods correspond to Hooks?](#how-do-lifecycle-methods-correspond-to-hooks)
+ * [How can I do data fetching with Hooks?](#how-can-i-do-data-fetching-with-hooks)
* [Is there something like instance variables?](#is-there-something-like-instance-variables)
* [Should I use one or many state variables?](#should-i-use-one-or-many-state-variables)
* [Can I run an effect only on updates?](#can-i-run-an-effect-only-on-updates)
* [How to get the previous props or state?](#how-to-get-the-previous-props-or-state)
+ * [Why am I seeing stale props or state inside my function?](#why-am-i-seeing-stale-props-or-state-inside-my-function)
* [How do I implement getDerivedStateFromProps?](#how-do-i-implement-getderivedstatefromprops)
* [Is there something like forceUpdate?](#is-there-something-like-forceupdate)
* [Can I make a ref to a function component?](#can-i-make-a-ref-to-a-function-component)
+ * [How can I measure a DOM node?](#how-can-i-measure-a-dom-node)
* [What does const [thing, setThing] = useState() mean?](#what-does-const-thing-setthing--usestate-mean)
* **[Performance Optimizations](#performance-optimizations)**
* [Can I skip an effect on updates?](#can-i-skip-an-effect-on-updates)
+ * [Is it safe to omit functions from the list of dependencies?](#is-it-safe-to-omit-functions-from-the-list-of-dependencies)
+ * [What can I do if my effect dependencies change too often?](#what-can-i-do-if-my-effect-dependencies-change-too-often)
* [How do I implement shouldComponentUpdate?](#how-do-i-implement-shouldcomponentupdate)
* [How to memoize calculations?](#how-to-memoize-calculations)
* [How to create expensive objects lazily?](#how-to-create-expensive-objects-lazily)
@@ -204,6 +209,10 @@ There are a few more heuristics, and they might change over time as we fine-tune
* `componentDidCatch` and `getDerivedStateFromError`: There are no Hook equivalents for these methods yet, but they will be added soon.
+### How can I do data fetching with Hooks?
+
+Here is a [small demo](https://codesandbox.io/s/jvvkoo8pq3) to get you started. To learn more, check out [this article](https://www.robinwieruch.de/react-hooks-fetch-data/) about data fetching with Hooks.
+
### Is there something like instance variables? {#is-there-something-like-instance-variables}
Yes! The [`useRef()`](/docs/hooks-reference.html#useref) Hook isn't just for DOM refs. The "ref" object is a generic container whose `current` property is mutable and can hold any value, similar to an instance property on a class.
@@ -362,6 +371,44 @@ It's possible that in the future React will provide a `usePrevious` Hook out of
See also [the recommended pattern for derived state](#how-do-i-implement-getderivedstatefromprops).
+### Why am I seeing stale props or state inside my function? {#why-am-i-seeing-stale-props-or-state-inside-my-function}
+
+Any function inside a component, including event handlers and effects, "sees" the props and state from the render it was created in. For example, consider code like this:
+
+```js
+function Example() {
+ const [count, setCount] = useState(0);
+
+ function handleAlertClick() {
+ setTimeout(() => {
+ alert('You clicked on: ' + count);
+ }, 3000);
+ }
+
+ return (
+
+
You clicked {count} times
+
+
+
+ );
+}
+```
+
+If you first click "Show alert" and then increment the counter, the alert will show the `count` variable **at the time you clicked the "Show alert" button**. This prevents bugs caused by the code assuming props and state don't change.
+
+If you intentionally want to read the *latest* state from some asynchronous callback, you could keep it in [a ref](/docs/hooks-faq.html#is-there-something-like-instance-variables), mutate it, and read from it.
+
+Finally, another possible reason you're seeing stale props or state is if you use the "dependency array" optimization but didn't correctly specify all the dependencies. For example, if an effect specifies `[]` as the second argument but reads `someProp` inside, it will keep "seeing" the initial value of `someProp`. The solution is to either remove the dependency array, or to fix it. Here's [how you can deal with functions](#is-it-safe-to-omit-functions-from-the-list-of-dependencies), and here's [other common strategies](#what-can-i-do-if-my-effect-dependencies-change-too-often) to run effects less often without incorrectly skipping dependencies.
+
+>Note
+>
+>We provide an [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) ESLint rule as a part of the [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix.
+
### How do I implement `getDerivedStateFromProps`? {#how-do-i-implement-getderivedstatefromprops}
While you probably [don't need it](/blog/2018/06/07/you-probably-dont-need-derived-state.html), in rare cases that you do (such as implementing a `` component), you can update the state right during rendering. React will re-run the component with updated state immediately after exiting the first render so it wouldn't be expensive.
@@ -405,6 +452,60 @@ Try to avoid this pattern if possible.
While you shouldn't need this often, you may expose some imperative methods to a parent component with the [`useImperativeHandle`](/docs/hooks-reference.html#useimperativehandle) Hook.
+### How can I measure a DOM node? {#how-can-i-measure-a-dom-node}
+
+In order to measure the position or size of a DOM node, you can use a [callback ref](/docs/refs-and-the-dom.html#callback-refs). React will call that callback whenever the ref gets attached to a different node. Here is a [small demo](https://codesandbox.io/s/l7m0v5x4v9):
+
+```js{4-8,12}
+function MeasureExample() {
+ const [height, setHeight] = useState(0);
+
+ const measuredRef = useCallback(node => {
+ if (node !== null) {
+ setHeight(node.getBoundingClientRect().height);
+ }
+ }, []);
+
+ return (
+ <>
+
Hello, world
+
The above header is {Math.round(height)}px tall
+ >
+ );
+}
+```
+
+We didn't choose `useRef` in this example because an object ref doesn't notify us about *changes* to the current ref value. Using a callback ref ensures that [even if a child component displays the measured node later](https://codesandbox.io/s/818zzk8m78) (e.g. in response to a click), we still get notified about it in the parent component and can update the measurements.
+
+Note that we pass `[]` as a dependency array to `useCallback`. This ensures that our ref callback doesn't change between the re-renders, and so React won't call it unnecessarily.
+
+If you want, you can [extract this logic](https://codesandbox.io/s/m5o42082xy) into a reusable Hook:
+
+```js{2}
+function MeasureExample() {
+ const [rect, ref] = useClientRect();
+ return (
+ <>
+
Hello, world
+ {rect !== null &&
+
The above header is {Math.round(rect.height)}px tall
+ }
+ >
+ );
+}
+
+function useClientRect() {
+ const [rect, setRect] = useState(null);
+ const ref = useCallback(node => {
+ if (node !== null) {
+ setRect(node.getBoundingClientRect());
+ }
+ }, []);
+ return [rect, ref];
+}
+```
+
+
### What does `const [thing, setThing] = useState()` mean? {#what-does-const-thing-setthing--usestate-mean}
If you're not familiar with this syntax, check out the [explanation](/docs/hooks-state.html#tip-what-do-square-brackets-mean) in the State Hook documentation.
@@ -416,6 +517,207 @@ If you're not familiar with this syntax, check out the [explanation](/docs/hooks
Yes. See [conditionally firing an effect](/docs/hooks-reference.html#conditionally-firing-an-effect). Note that forgetting to handle updates often [introduces bugs](/docs/hooks-effect.html#explanation-why-effects-run-on-each-update), which is why this isn't the default behavior.
+### Is it safe to omit functions from the list of dependencies? {#is-it-safe-to-omit-functions-from-the-list-of-dependencies}
+
+Generally speaking, no.
+
+```js{3,8}
+function Example({ someProp }) {
+ function doSomething() {
+ console.log(someProp);
+ }
+
+ useEffect(() => {
+ doSomething();
+ }, []); // 🔴 This is not safe (it calls `doSomething` which uses `someProp`)
+}
+```
+
+It's difficult to remember which props or state are used by functions outside of the effect. This is why **usually you'll want to declare functions needed by an effect *inside* of it.** Then it's easy to see what values from the component scope that effect depends on:
+
+```js{4,8}
+function Example({ someProp }) {
+ useEffect(() => {
+ function doSomething() {
+ console.log(someProp);
+ }
+
+ doSomething();
+ }, [someProp]); // ✅ OK (our effect only uses `someProp`)
+}
+```
+
+If after that we still don't use any values from the component scope, it's safe to specify `[]`:
+
+```js{7}
+useEffect(() => {
+ function doSomething() {
+ console.log('hello');
+ }
+
+ doSomething();
+}, []); // ✅ OK in this example because we don't use *any* values from component scope
+```
+
+Depending on your use case, there are a few more options described below.
+
+>Note
+>
+>We provide the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) ESLint rule as a part of the [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It help you find components that don't handle updates consistently.
+
+Let's see why this matters.
+
+If you specify a [list of dependencies](/docs/hooks-reference.html#conditionally-firing-an-effect) as the last argument to `useEffect`, `useMemo`, `useCallback`, or `useImperativeHandle`, it must include all values used inside that participate in the React data flow. That includes props, state, and anything derived from them.
+
+It is **only** safe to omit a function from the dependency list if nothing in it (or the functions called by it) references props, state, or values derived from them. This example has a bug:
+
+```js{5,12}
+function ProductPage({ productId }) {
+ const [product, setProduct] = useState(null);
+
+ async function fetchProduct() {
+ const response = await fetch('http://myapi/product' + productId); // Uses productId prop
+ const json = await response.json();
+ setProduct(json);
+ }
+
+ useEffect(() => {
+ fetchProduct();
+ }, []); // 🔴 Invalid because `fetchProduct` uses `productId`
+ // ...
+}
+```
+
+**The recommended fix is to move that function _inside_ of your effect**. That makes it easy to see which props or state your effect uses, and to ensure they're all declared:
+
+```js{5-10,13}
+function ProductPage({ productId }) {
+ const [product, setProduct] = useState(null);
+
+ useEffect(() => {
+ // By moving this function inside the effect, we can clearly see the values it uses.
+ async function fetchProduct() {
+ const response = await fetch('http://myapi/product' + productId);
+ const json = await response.json();
+ setProduct(json);
+ }
+
+ fetchProduct();
+ }, [productId]); // ✅ Valid because our effect only uses productId
+ // ...
+}
+```
+
+This also allows you to handle out-of-order responses with a local variable inside the effect:
+
+```js{2,6,8}
+ useEffect(() => {
+ let ignore = false;
+ async function fetchProduct() {
+ const response = await fetch('http://myapi/product/' + productId);
+ const json = await response.json();
+ if (!ignore) setProduct(json);
+ }
+ return () => { ignore = true };
+ }, [productId]);
+```
+
+We moved the function inside the effect so it doesn't need to be in its dependency list.
+
+>Tip
+>
+>Check out [this small demo](https://codesandbox.io/s/jvvkoo8pq3) and [this article](https://www.robinwieruch.de/react-hooks-fetch-data/) to learn more about data fetching with Hooks.
+
+**If for some reason you _can't_ move a function inside an effect, there are a few more options:**
+
+* **You can try moving that function outside of your component**. In that case, the function is guaranteed to not reference any props or state, and also doesn't need to be in the list of dependencies.
+* If the function you're calling is a pure computation and is safe to call while rendering, you may **call it outside of the effect instead,** and make the effect depend on the returned value.
+* As a last resort, you can **add a function to effect dependencies but _wrap its definition_** into the [`useCallback`](/docs/hooks-reference.html#usecallback) Hook. This ensures it doesn't change on every render unless *its own* dependencies also change:
+
+```js{2-5}
+function ProductPage({ productId }) {
+ // ✅ Wrap with useCallback to avoid change on every render
+ const fetchProduct = useCallback(() => {
+ // ... Does something with productId ...
+ }, [productId]); // ✅ All useCallback dependencies are specified
+
+ return ;
+}
+
+function ProductDetails({ fetchProduct })
+ useEffect(() => {
+ fetchProduct();
+ }, [fetchProduct]); // ✅ All useEffect dependencies are specified
+ // ...
+}
+```
+
+Note that in the above example we **need** to keep the function in the dependencies list. This ensures that a change in the `productId` prop of `ProductPage` automatically triggers a refetch in the `ProductDetails` component.
+
+### What can I do if my effect dependencies change too often?
+
+Sometimes, your effect may be using reading state that changes too often. You might be tempted to omit that state from a list of dependencies, but that usually leads to bugs:
+
+```js{6,9}
+function Counter() {
+ const [count, setCount] = useState(0);
+
+ useEffect(() => {
+ const id = setInterval(() => {
+ setCount(count + 1); // This effect depends on the `count` state
+ }, 1000);
+ return () => clearInterval(id);
+ }, []); // 🔴 Bug: `count` is not specified as a dependency
+
+ return
{count}
;
+}
+```
+
+Specifying `[count]` as a list of dependencies would fix the bug, but would cause the interval to be reset on every change. That may not be desirable. To fix this, we can use the [functional update form of `setState`](/docs/hooks-reference.html#functional-updates). It lets us specify *how* the state needs to change without referencing the *current* state:
+
+```js{6,9}
+function Counter() {
+ const [count, setCount] = useState(0);
+
+ useEffect(() => {
+ const id = setInterval(() => {
+ setCount(c => c + 1); // ✅ This doesn't depend on `count` variable outside
+ }, 1000);
+ return () => clearInterval(id);
+ }, []); // ✅ Our effect doesn't use any variables in the component scope
+
+ return
{count}
;
+}
+```
+
+(The identity of the `setCount` function is guaranteed to be stable so it's safe to omit.)
+
+In more complex cases (such as if one state depends on another state), try moving the state update logic outside the effect with the [`useReducer` Hook](/docs/hooks-reference.html#usereducer). [This article](https://adamrackis.dev/state-and-use-reducer/) offers an example of how you can do this. **The identity of the `dispatch` function from `useReducer` is always stable** — even if the reducer function is declared inside the component and reads its props.
+
+As a last resort, if you want to something like `this` in a class, you can [use a ref](/docs/hooks-faq.html#is-there-something-like-instance-variables) to hold a mutable variable. Then you can write and read to it. For example:
+
+```js{2-6,10-11,16}
+function Example(props) {
+ // Keep latest props in a ref.
+ let latestProps = useRef(props);
+ useEffect(() => {
+ latestProps.current = props;
+ });
+
+ useEffect(() => {
+ function tick() {
+ // Read latest props at any time
+ console.log(latestProps.current);
+ }
+
+ const id = setInterval(tick, 1000);
+ return () => clearInterval(id);
+ }, []); // This effect never re-runs
+}
+```
+
+Only do this if you couldn't find a better alternative, as relying on mutation makes components less predictable. If there's a specific pattern that doesn't translate well, [file an issue](https://github.com/facebook/react/issues/new) with a runnable example code and we can try to help.
+
### How do I implement `shouldComponentUpdate`? {#how-do-i-implement-shouldcomponentupdate}
You can wrap a function component with `React.memo` to shallowly compare its props:
@@ -430,7 +732,6 @@ It's not a Hook because it doesn't compose like Hooks do. `React.memo` is equiva
`React.memo` doesn't compare state because there is no single state object to compare. But you can make children pure too, or even [optimize individual children with `useMemo`](/docs/hooks-faq.html#how-to-memoize-calculations).
-
### How to memoize calculations? {#how-to-memoize-calculations}
The [`useMemo`](/docs/hooks-reference.html#usememo) Hook lets you cache calculations between multiple renders by "remembering" the previous computation:
@@ -607,7 +908,7 @@ function Form() {
const [text, updateText] = useState('');
const textRef = useRef();
- useLayoutEffect(() => {
+ useEffect(() => {
textRef.current = text; // Write it to the ref
});
@@ -648,7 +949,7 @@ function useEventCallback(fn, dependencies) {
throw new Error('Cannot call an event handler while rendering.');
});
- useLayoutEffect(() => {
+ useEffect(() => {
ref.current = fn;
}, [fn, ...dependencies]);
diff --git a/content/docs/hooks-reference.md b/content/docs/hooks-reference.md
index deeef54cf..98c2e14c0 100644
--- a/content/docs/hooks-reference.md
+++ b/content/docs/hooks-reference.md
@@ -45,6 +45,10 @@ setState(newState);
During subsequent re-renders, the first value returned by `useState` will always be the most recent state after applying updates.
+>Note
+>
+>React guarantees that `setState` function identity is stable and won't change on re-renders. This is why it's safe to omit from the `useEffect` or `useCallback` dependency list.
+
#### Functional updates {#functional-updates}
If the new state is computed using the previous state, you can pass a function to `setState`. The function will receive the previous value, and return an updated value. Here's an example of a counter component that uses both forms of `setState`:
@@ -93,6 +97,8 @@ const [state, setState] = useState(() => {
If you update a State Hook to the same value as the current state, React will bail out without rendering the children or firing effects. (React uses the [`Object.is` comparison algorithm](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description).)
+Note that React may still need to render that specific component again before bailing out. That shouldn't be a concern because React won't unnecessarily go "deeper" into the tree. If you're doing expensive calculations while rendering, you can optimize them with `useMemo`.
+
### `useEffect` {#useeffect}
```js
@@ -133,7 +139,7 @@ Although `useEffect` is deferred until after the browser has painted, it's guara
#### Conditionally firing an effect {#conditionally-firing-an-effect}
-The default behavior for effects is to fire the effect after every completed render. That way an effect is always recreated if one of its inputs changes.
+The default behavior for effects is to fire the effect after every completed render. That way an effect is always recreated if one of its dependencies changes.
However, this may be overkill in some cases, like the subscription example from the previous section. We don't need to create a new subscription on every update, only if the `source` props has changed.
@@ -153,21 +159,42 @@ useEffect(
Now the subscription will only be recreated when `props.source` changes.
-Passing in an empty array `[]` of inputs tells React that your effect doesn't depend on any values from the component, so that effect would run only on mount and clean up on unmount; it won't run on updates.
-
-> Note
+>Note
+>
+>If you use this optimization, make sure the array includes **all values from the component scope (such as props and state) that change over time and that are used by the effect**. Otherwise, your code will reference stale values from previous renders. Learn more about [how to deal with functions](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) and what to do when the [array values change too often](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often).
>
-> The array of inputs is not passed as arguments to the effect function. Conceptually, though, that's what they represent: every value referenced inside the effect function should also appear in the inputs array. In the future, a sufficiently advanced compiler could create this array automatically.
+>If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array (`[]`) as a second argument. This tells React that your effect doesn't depend on *any* values from props or state, so it never needs to re-run. This isn't handled as a special case -- it follows directly from how the dependencies array always works.
+>
+>If you pass an empty array (`[]`), the props and state as inside the effect will always have their initial values. While passing `[]` as the second argument is closer to the familiar `componentDidMount` and `componentWillUnmount` mental model, there are usually [better](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) [solutions](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often) to avoid re-running effects too often. Also, don't forget that React defers running `useEffect` until after the browser has painted, so doing extra work is less of a problem.
+>
+>
+>We recommend using the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) rule as part of our [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix.
+
+The array of dependencies is not passed as arguments to the effect function. Conceptually, though, that's what they represent: every value referenced inside the effect function should also appear in the dependencies array. In the future, a sufficiently advanced compiler could create this array automatically.
### `useContext` {#usecontext}
```js
-const context = useContext(Context);
+const value = useContext(MyContext);
```
-Accepts a context object (the value returned from `React.createContext`) and returns the current context value, as given by the nearest context provider for the given context.
+Accepts a context object (the value returned from `React.createContext`) and returns the current context value for that context. The current context value is determined by the `value` prop of the nearest `` above the calling component in the tree.
-When the provider updates, this Hook will trigger a rerender with the latest context value.
+When the nearest `` above the component updates, this Hook will trigger a rerender with the latest context `value` passed to that `MyContext` provider.
+
+Don't forget that the argument to `useContext` must be the *context object itself*:
+
+ * **Correct:** `useContext(MyContext)`
+ * **Incorrect:** `useContext(MyContext.Consumer)`
+ * **Incorrect:** `useContext(MyContext.Provider)`
+
+A component calling `useContext` will always re-render when the context value changes. If re-rendering the component is expensive, you can [optimize it by using memoization](https://github.com/facebook/react/issues/15156#issuecomment-474590693).
+
+>Tip
+>
+>If you're familiar with the context API before Hooks, `useContext(MyContext)` is equivalent to `static contextType = MyContext` in a class, or to ``.
+>
+>`useContext(MyContext)` only lets you *read* the context and subscribe to its changes. You still need a `` above in the tree to *provide* the value for this context.
## Additional Hooks {#additional-hooks}
@@ -211,6 +238,10 @@ function Counter({initialState}) {
}
```
+>Note
+>
+>React guarantees that `dispatch` function identity is stable and won't change on re-renders. This is why it's safe to omit from the `useEffect` or `useCallback` dependency list.
+
#### Specifying the initial state {#specifying-the-initial-state}
There’s two different ways to initialize `useReducer` state. You may choose either one depending on the use case. The simplest way to pass the initial state as a second argument:
@@ -270,6 +301,8 @@ function Counter({initialCount}) {
If you return the same value from a Reducer Hook as the current state, React will bail out without rendering the children or firing effects. (React uses the [`Object.is` comparison algorithm](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description).)
+Note that React may still need to render that specific component again before bailing out. That shouldn't be a concern because React won't unnecessarily go "deeper" into the tree. If you're doing expensive calculations while rendering, you can optimize them with `useMemo`.
+
### `useCallback` {#usecallback}
```js
@@ -283,13 +316,15 @@ const memoizedCallback = useCallback(
Returns a [memoized](https://en.wikipedia.org/wiki/Memoization) callback.
-Pass an inline callback and an array of inputs. `useCallback` will return a memoized version of the callback that only changes if one of the inputs has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. `shouldComponentUpdate`).
+Pass an inline callback and an array of dependencies. `useCallback` will return a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. `shouldComponentUpdate`).
-`useCallback(fn, inputs)` is equivalent to `useMemo(() => fn, inputs)`.
+`useCallback(fn, deps)` is equivalent to `useMemo(() => fn, deps)`.
> Note
>
-> The array of inputs is not passed as arguments to the callback. Conceptually, though, that's what they represent: every value referenced inside the callback should also appear in the inputs array. In the future, a sufficiently advanced compiler could create this array automatically.
+> The array of dependencies is not passed as arguments to the callback. Conceptually, though, that's what they represent: every value referenced inside the callback should also appear in the dependencies array. In the future, a sufficiently advanced compiler could create this array automatically.
+>
+> We recommend using the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) rule as part of our [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix.
### `useMemo` {#usememo}
@@ -299,17 +334,19 @@ const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Returns a [memoized](https://en.wikipedia.org/wiki/Memoization) value.
-Pass a "create" function and an array of inputs. `useMemo` will only recompute the memoized value when one of the inputs has changed. This optimization helps to avoid expensive calculations on every render.
+Pass a "create" function and an array of dependencies. `useMemo` will only recompute the memoized value when one of the dependencies has changed. This optimization helps to avoid expensive calculations on every render.
Remember that the function passed to `useMemo` runs during rendering. Don't do anything there that you wouldn't normally do while rendering. For example, side effects belong in `useEffect`, not `useMemo`.
-If no array is provided, a new value will be computed whenever a new function instance is passed as the first argument. (With an inline function, on every render.)
+If no array is provided, a new value will be computed on every render.
**You may rely on `useMemo` as a performance optimization, not as a semantic guarantee.** In the future, React may choose to "forget" some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. Write your code so that it still works without `useMemo` — and then add it to optimize performance.
> Note
>
-> The array of inputs is not passed as arguments to the function. Conceptually, though, that's what they represent: every value referenced inside the function should also appear in the inputs array. In the future, a sufficiently advanced compiler could create this array automatically.
+> The array of dependencies is not passed as arguments to the function. Conceptually, though, that's what they represent: every value referenced inside the function should also appear in the dependencies array. In the future, a sufficiently advanced compiler could create this array automatically.
+>
+> We recommend using the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) rule as part of our [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix.
### `useRef` {#useref}
@@ -337,12 +374,21 @@ function TextInputWithFocusButton() {
}
```
-Note that `useRef()` is useful for more than the `ref` attribute. It's [handy for keeping any mutable value around](/docs/hooks-faq.html#is-there-something-like-instance-variables) similar to how you'd use instance fields in classes.
+Essentially, `useRef` is like a "box" that can hold a mutable value in its `.current` property.
+
+You might be familiar with refs primarily as a way to [access the DOM](/docs/refs-and-the-dom.html). If you pass a ref object to React with ``, React will set its `.current` property to the corresponding DOM node whenever that node changes.
+
+However, `useRef()` is useful for more than the `ref` attribute. It's [handy for keeping any mutable value around](/docs/hooks-faq.html#is-there-something-like-instance-variables) similar to how you'd use instance fields in classes.
+
+This works because `useRef()` creates a plain JavaScript object. The only difference between `useRef()` and creating a `{current: ...}` object yourself is that `useRef` will give you the same ref object on every render.
+
+Keep in mind that `useRef` *doesn't* notify you when its content changes. Mutating the `.current` property doesn't cause a re-render. If you want to run some code when React attaches or detaches a ref to a DOM node, you may want to use a [callback ref](/docs/hooks-faq.html#how-can-i-measure-a-dom-node) instead.
+
### `useImperativeHandle` {#useimperativehandle}
```js
-useImperativeHandle(ref, createHandle, [inputs])
+useImperativeHandle(ref, createHandle, [deps])
```
`useImperativeHandle` customizes the instance value that is exposed to parent components when using `ref`. As always, imperative code using refs should be avoided in most cases. `useImperativeHandle` should be used with `forwardRef`:
@@ -370,7 +416,11 @@ Prefer the standard `useEffect` when possible to avoid blocking visual updates.
> Tip
>
-> If you're migrating code from a class component, `useLayoutEffect` fires in the same phase as `componentDidMount` and `componentDidUpdate`, so if you're unsure of which effect Hook to use, it's probably the least risky.
+> If you're migrating code from a class component, note `useLayoutEffect` fires in the same phase as `componentDidMount` and `componentDidUpdate`. However, **we recommend starting with `useEffect` first** and only trying `useLayoutEffect` if that causes a problem.
+>
+>If you use server rendering, keep in mind that *neither* `useLayoutEffect` nor `useEffect` can run until the JavaScript is downloaded. This is why React warns when a server-rendered component contains `useLayoutEffect`. To fix this, either move that logic to `useEffect` (if it isn't necessary for the first render), or delay showing that component until after the client renders (if the HTML looks broken until `useLayoutEffect` runs).
+>
+>To exclude a component that needs layout effects from the server-rendered HTML, render it conditionally with `showChild && ` and defer showing it with `useEffect(() => { setShowChild(true); }, [])`. This way, the UI doesn't appear broken before hydration.
### `useDebugValue` {#usedebugvalue}
diff --git a/content/docs/hooks-rules.md b/content/docs/hooks-rules.md
index 698d1c741..dbac9cffd 100644
--- a/content/docs/hooks-rules.md
+++ b/content/docs/hooks-rules.md
@@ -40,7 +40,8 @@ npm install eslint-plugin-react-hooks
],
"rules": {
// ...
- "react-hooks/rules-of-hooks": "error"
+ "react-hooks/rules-of-hooks": "error", // Checks rules of Hooks
+ "react-hooks/exhaustive-deps": "warn" // Checks effect dependencies
}
}
```
diff --git a/content/docs/render-props.md b/content/docs/render-props.md
index c9b6f9c04..e1482f491 100644
--- a/content/docs/render-props.md
+++ b/content/docs/render-props.md
@@ -14,7 +14,7 @@ A component with a render prop takes a function that returns a React element and
)}/>
```
-Libraries that use render props include [React Router](https://reacttraining.com/react-router/web/api/Route/Route-render-methods) and [Downshift](https://github.com/paypal/downshift).
+Libraries that use render props include [React Router](https://reacttraining.com/react-router/web/api/Route/render-func) and [Downshift](https://github.com/paypal/downshift).
In this document, we’ll discuss why render props are useful, and how to write your own.
diff --git a/content/docs/state-and-lifecycle.md b/content/docs/state-and-lifecycle.md
index cbd8f684a..e6d85ae57 100644
--- a/content/docs/state-and-lifecycle.md
+++ b/content/docs/state-and-lifecycle.md
@@ -1,6 +1,6 @@
---
id: state-and-lifecycle
-title: State and Lifecycle
+title: state و lifecycle
permalink: docs/state-and-lifecycle.html
redirect_from:
- "docs/interactivity-and-dynamic-uis.html"
@@ -8,9 +8,9 @@ prev: components-and-props.html
next: handling-events.html
---
-This page introduces the concept of state and lifecycle in a React component. You can find a [detailed component API reference here](/docs/react-component.html).
+این صفحه مفهوم state و lifecycle را در یک کامپوننت ریاکتی معرفی میکند. برای مطالعه [مرجع API کامپوننت با جزئیات به اینجا](/docs/react-component.html) مراجعه کنید.
-Consider the ticking clock example from [one of the previous sections](/docs/rendering-elements.html#updating-the-rendered-element). In [Rendering Elements](/docs/rendering-elements.html#rendering-an-element-into-the-dom), we have only learned one way to update the UI. We call `ReactDOM.render()` to change the rendered output:
+مثال ساعت را در [یکی از بخشهای پیشین](/docs/rendering-elements.html#updating-the-rendered-element) در نظر بگیرید. در [رندر کردن المنتها](/docs/rendering-elements.html#rendering-an-element-into-the-dom)، ما تنها یک راه برای بهروز رسانی UI یاد گرفتیم. ما تابع `ReactDOM.render()` را فراخوانی میکنیم تا خروجی رندر شده را تغییر دهیم:
```js{8-11}
function tick() {
@@ -29,11 +29,11 @@ function tick() {
setInterval(tick, 1000);
```
-[**Try it on CodePen**](https://codepen.io/gaearon/pen/gwoJZk?editors=0010)
+[**روی CodePen امتحان کنید**](https://codepen.io/gaearon/pen/gwoJZk?editors=0010)
-In this section, we will learn how to make the `Clock` component truly reusable and encapsulated. It will set up its own timer and update itself every second.
+در این بخش یاد میگیریم که چگونه کامپوننت `Clock` را واقعا قابل استفاده مجدد و کپسوله کنیم. به طوری که خودش تایمرش را تنظیم و هر ثانیه خودش را بهروز رسانی کند.
-We can start by encapsulating how the clock looks:
+می تونیم با کپسوله کردن ظاهر ساعت شروع کنیم:
```js{3-6,12}
function Clock(props) {
@@ -55,11 +55,11 @@ function tick() {
setInterval(tick, 1000);
```
-[**Try it on CodePen**](https://codepen.io/gaearon/pen/dpdoYR?editors=0010)
+[**روی CodePen امتحان کنید**](https://codepen.io/gaearon/pen/dpdoYR?editors=0010)
-However, it misses a crucial requirement: the fact that the `Clock` sets up a timer and updates the UI every second should be an implementation detail of the `Clock`.
+اگرچه، یک نیاز حیاتی را از دست میدهد: این که `Clock` یک تایمر را تنظیم و هر ثانیه UI را بهروز رسانی کند، که باید بخشی از جزئیات پیادهسازی خود `Clock` باشد.
-Ideally we want to write this once and have the `Clock` update itself:
+ایدهآل این است که ما یک بار `Clock` را بنویسیم و خودش بهروز رسانی را انجام دهد:
```js{2}
ReactDOM.render(
@@ -68,25 +68,26 @@ ReactDOM.render(
);
```
-To implement this, we need to add "state" to the `Clock` component.
+برای پیادهسازی آن، باید به کامپوننت `Clock` state اضافه کنیم.
-State is similar to props, but it is private and fully controlled by the component.
+state مشابه props است، اما خصوصی است و کاملا توسط کامپوننت کنترل میشود.
-We [mentioned before](/docs/components-and-props.html#functional-and-class-components) that components defined as classes have some additional features. Local state is exactly that: a feature available only to classes.
+ما [قبلا ذکر کردیم](/docs/components-and-props.html#functional-and-class-components) به کامپوننتهایی که به صورت کلاس تعریف میشوند، قابلیتهایی افزوده میشود. state داخلی دقیقا همان است: قابلیتی که فقط برای کلاسها موجود است.
-## Converting a Function to a Class {#converting-a-function-to-a-class}
-You can convert a function component like `Clock` to a class in five steps:
+## تبدیل یک تابع به یک کلاس {#converting-a-function-to-a-class}
-1. Create an [ES6 class](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes), with the same name, that extends `React.Component`.
+شما میتوانید یک کامپوننت برپایه تابع را در پنج مرحله به یک کلاس تبدیل کنید:
-2. Add a single empty method to it called `render()`.
+1. یک [کلاس ES6](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes) بسازید، با همان نام که از `React.Component` ارث میبرد.
-3. Move the body of the function into the `render()` method.
+2. یک متد خالی با نام `render()` به آن اضافه کنید.
-4. Replace `props` with `this.props` in the `render()` body.
+3. بدنه تابع را به متد `render()` منتقل کنید.
-5. Delete the remaining empty function declaration.
+4. در بدنه `render()` بهجای `props`، `this.props` بنویسید.
+
+5. آنچه از تعریف تابع خالی باقی ماندهاست را پاک کنید.
```js
class Clock extends React.Component {
@@ -101,17 +102,18 @@ class Clock extends React.Component {
}
```
-[**Try it on CodePen**](https://codepen.io/gaearon/pen/zKRGpo?editors=0010)
+[**روی CodePen امتحان کنید**](https://codepen.io/gaearon/pen/zKRGpo?editors=0010)
+
+حالا `Clock` به جای تابع، به صورت کلاس تعریف شدهاست.
-`Clock` is now defined as a class rather than a function.
+هربار که بهروز رسانی اتفاق میافتد، تابع `render` فراخوانی میشود. اما تا وقتی که ما `` را درون همان DOM node رندر میکنیم، تنها یک نمونه از کلاس `Clock` استفاده خواهدشد. این باعث میشود ما قادر به استفاده از ویژگیهای دیگری مانند state و توابع lifecycle باشیم.
-The `render` method will be called each time an update happens, but as long as we render `` into the same DOM node, only a single instance of the `Clock` class will be used. This lets us use additional features such as local state and lifecycle methods.
-## Adding Local State to a Class {#adding-local-state-to-a-class}
+## اضافهکردن state داخلی به یک کلاس {#adding-local-state-to-a-class}
-We will move the `date` from props to state in three steps:
+ما در سه مرحله، `date` را از props به state انتقال میدهیم:
-1) Replace `this.props.date` with `this.state.date` in the `render()` method:
+1. در تابع `render()`، `this.props.date` را با `this.state.date` جایگزین کنید:
```js{6}
class Clock extends React.Component {
@@ -126,7 +128,7 @@ class Clock extends React.Component {
}
```
-2) Add a [class constructor](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes#Constructor) that assigns the initial `this.state`:
+2. یک [سازنده کلاس](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes#Constructor) اضافه کنید که مقداردهی اولیه `this.state` را انجام میدهد:
```js{4}
class Clock extends React.Component {
@@ -146,7 +148,7 @@ class Clock extends React.Component {
}
```
-Note how we pass `props` to the base constructor:
+آگاه باشید که ما چگونه `props` را به سازنده پدر پاس میدهیم:
```js{2}
constructor(props) {
@@ -155,9 +157,9 @@ Note how we pass `props` to the base constructor:
}
```
-Class components should always call the base constructor with `props`.
+کامپوننتهای بر پایه کلاس باید همیشه سازنده پدر را با `props` فراخوانی کنند.
-3) Remove the `date` prop from the `` element:
+3. `date` را از props المنت `` حذف کنید:
```js{2}
ReactDOM.render(
@@ -166,9 +168,9 @@ ReactDOM.render(
);
```
-We will later add the timer code back to the component itself.
+ما بعدا کد مربوط به تایمر را به خود کامپوننت اضافهمی کنیم.
-The result looks like this:
+نتیجه این شدهاست:
```js{2-5,11,18}
class Clock extends React.Component {
@@ -193,19 +195,19 @@ ReactDOM.render(
);
```
-[**Try it on CodePen**](https://codepen.io/gaearon/pen/KgQpJd?editors=0010)
+[**روی CodePen امتحان کنید**](https://codepen.io/gaearon/pen/KgQpJd?editors=0010)
-Next, we'll make the `Clock` set up its own timer and update itself every second.
+در ادامه، `Clock` را طوری تغییر میدهیم که تایمر خودش را داشتهباشد و خودش هر ثانیه بهروز رسانی شود.
-## Adding Lifecycle Methods to a Class {#adding-lifecycle-methods-to-a-class}
+## افزودن توابع lifecycle به یک کلاس {#adding-lifecycle-methods-to-a-class}
-In applications with many components, it's very important to free up resources taken by the components when they are destroyed.
+در برنامههایی با تعداد کامپوننت زیاد، بسیار اهمیت دارد که با از بین رفتن کامپوننت، منابعی که توسط آن اشغال شدهبود نیز آزاد شود.
-We want to [set up a timer](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) whenever the `Clock` is rendered to the DOM for the first time. This is called "mounting" in React.
+ما می خواهیم [یک تایمر](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) را برای اولین دفعهای که `Clock` در DOM رندر میشود، تنظیم کنیم. در ریاکت به آن "mounting" گفته میشود.
-We also want to [clear that timer](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval) whenever the DOM produced by the `Clock` is removed. This is called "unmounting" in React.
+همچنین میخواهیم هر زمان که DOM تولید شده توسط `Clock` حذف میشود، [تایمر را پاک کنیم](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval). در ریاکت به آن "unmounting" گفته میشود.
-We can declare special methods on the component class to run some code when a component mounts and unmounts:
+برای اجرای کدهایی زمان mount و unmount شدن یک کامپوننت، ما می توانیم توابع ویژهای روی کامپوننتهای بر پایه کلاس تعریف کنیم:
```js{7-9,11-13}
class Clock extends React.Component {
@@ -233,9 +235,9 @@ class Clock extends React.Component {
}
```
-These methods are called "lifecycle methods".
+به آنها "توابع lifecycle" گفته میشود.
-The `componentDidMount()` method runs after the component output has been rendered to the DOM. This is a good place to set up a timer:
+تابع `componentDidMount()` پس از رندر شدن خروجی کامپوننت توی DOM، اجرا میشود. اینجا محل خوبی برای تنظیم یک تایمر است:
```js{2-5}
componentDidMount() {
@@ -246,11 +248,13 @@ The `componentDidMount()` method runs after the component output has been render
}
```
-Note how we save the timer ID right on `this`.
-While `this.props` is set up by React itself and `this.state` has a special meaning, you are free to add additional fields to the class manually if you need to store something that doesn’t participate in the data flow (like a timer ID).
-We will tear down the timer in the `componentWillUnmount()` lifecycle method:
+دقت داشتهباشید که چگونه ما شناسه تایمر را دقیقا روی `this` ذخیره میکنیم.
+
+در حالی که `this.props` توسط خود ریاکت تنظیم میشود و `this.state` کاربرد خاص خودش را دارد، شما آزاد هستید که برای ذخیره چیزی که نقشی در جریان دادهها ندارد (مانند شناسه تایمر)، به صورت دستی فیلدهای دیگری به کلاس اضافه کنید.
+
+ما تایمر را در تابع lifecycle `componentWillUnmount()` از کار میاندازیم:
```js{2}
componentWillUnmount() {
@@ -258,9 +262,9 @@ We will tear down the timer in the `componentWillUnmount()` lifecycle method:
}
```
-Finally, we will implement a method called `tick()` that the `Clock` component will run every second.
+در آخر، ما تابعی با نام `tick()` پیادهسازی میکنیم که کامپوننت `Clock` هر ثانیه آنرا فراخوانی میکند.
-It will use `this.setState()` to schedule updates to the component local state:
+این [تابع] از `this.setState()` استفاده می کند تا بهروز رسانیها را روی state داخلی کامپوننت انجام دهد:
```js{18-22}
class Clock extends React.Component {
@@ -302,72 +306,71 @@ ReactDOM.render(
);
```
-[**Try it on CodePen**](https://codepen.io/gaearon/pen/amqdNA?editors=0010)
+[**روی CodePen امتحان کنید**](https://codepen.io/gaearon/pen/amqdNA?editors=0010)
-Now the clock ticks every second.
+حالا ساعت هر ثانیه تغییر میکند.
-Let's quickly recap what's going on and the order in which the methods are called:
+بیایید به طور خلاصه جمعبندی کنیم که چه اتفاقی ره میدهد و به ترتیب چه توابعی فراخوانی میشوند:
-1) When `` is passed to `ReactDOM.render()`, React calls the constructor of the `Clock` component. Since `Clock` needs to display the current time, it initializes `this.state` with an object including the current time. We will later update this state.
+1. زمانی که `` به `ReactDOM.render()` پاس داده میشود، ریاکت سازنده کامپوننت `Clock` را فراخوانی میکند. از آنجایی که `Clock` زمان جاری را نمایش دهد، `this.state` را با شیءای شامل زمان جاری مقداردهی اولیه میکند.
-2) React then calls the `Clock` component's `render()` method. This is how React learns what should be displayed on the screen. React then updates the DOM to match the `Clock`'s render output.
+2. سپس ریاکت تابع `render()` کامپوننت `Clock` را فرا میخواند. این روشی است که ریاکت میفهمد چه چیزی باید روی صفجه نمایشداده شود. سپس ریاکت DOM را بهروز رسانی و با خروجی رندر `Clock` تطبیق میدهد.
-3) When the `Clock` output is inserted in the DOM, React calls the `componentDidMount()` lifecycle method. Inside it, the `Clock` component asks the browser to set up a timer to call the component's `tick()` method once a second.
+3. زمانی که خروجی `Clock` به DOM اضافه میشود، ریاکت تابع lifecycle `componentDidMount()` را فراخوانی میکند. درون آن، کامپوننت `Clock` از مرورگر میخواهد که یک تایمر تنظیم کند که هر ثانیه تابع `tick()` را فراخوانی کند.
-4) Every second the browser calls the `tick()` method. Inside it, the `Clock` component schedules a UI update by calling `setState()` with an object containing the current time. Thanks to the `setState()` call, React knows the state has changed, and calls the `render()` method again to learn what should be on the screen. This time, `this.state.date` in the `render()` method will be different, and so the render output will include the updated time. React updates the DOM accordingly.
+4. مرورگر هر ثانیه تابع `tick()` را فرا میخواند. درون آن، کامپوننت `Clock` بهروز رسانی UI را با فراخوانی تابع `setState()` همراه یک شیء شامل زمان جاری، زمانبندی میکند. ریاکت با کمک `setState()` متوجه میشود که state تغییر کردهاست. و آنگاه برای اطلاع از آنچه باید روی صفحه نمایش دادهشود، تابع `render()` را فرا میخواند. این دفعه، مقدار `this.state.date` در تابع `render()` متفاوت خواهد بود و بنابراین خروجی رندر دارای زمان بهروز رسانی شده خواهدبود. ریاکت DOM را بر همین اساس بهروز رسانی میکند.
-5) If the `Clock` component is ever removed from the DOM, React calls the `componentWillUnmount()` lifecycle method so the timer is stopped.
+5. اگر کامپوننت `Clock` از DOM حذف شود، ریاکت هم تابع lifecycle `componentWillUnmount()` را فرا میخواند و در نتیجه تایمر متوقف میشود.
-## Using State Correctly {#using-state-correctly}
+## استفاده صحیح از state {#using-state-correctly}
-There are three things you should know about `setState()`.
+سه چیز هست که باید درباره `setState()` بدانید:
-### Do Not Modify State Directly {#do-not-modify-state-directly}
+### مستقیم state را تغییر ندهید {#do-not-modify-state-directly}
-For example, this will not re-render a component:
+برای مثال، این کار باعث رندر مجدد یک کامپوننت نمیشود:
```js
-// Wrong
+// اشتباه
this.state.comment = 'Hello';
```
-Instead, use `setState()`:
+به جای آن از `setState()` استفاده کنید:
```js
-// Correct
+// درست
this.setState({comment: 'Hello'});
```
+تنها جایی که شما میتوانید `this.state` را [مستقیم] مقداردهی کنید، سازنده [کلاس] است.
-The only place where you can assign `this.state` is the constructor.
+### بهروز رسانی state ممکن است غیرهمزمان باشد {#state-updates-may-be-asynchronous}
-### State Updates May Be Asynchronous {#state-updates-may-be-asynchronous}
+ممکن است ریاکت برای بهبود عملکرد، فراخوانی چند باره `setState()` را در یک بهروز رسانی انجام دهد.
-React may batch multiple `setState()` calls into a single update for performance.
+از آنجا که ممکن است `this.props` و `this.state` به صورت غیرهمزمان بهروز رسانی شوند، برای محاسبه وضعیت بعدی نباید روی مقادیر آنها حساب کنید.
-Because `this.props` and `this.state` may be updated asynchronously, you should not rely on their values for calculating the next state.
-
-For example, this code may fail to update the counter:
+برای مثال، این کد ممکن است در بهروز رسانی شمارنده دچار اشکال شود:
```js
-// Wrong
+// اشتباه
this.setState({
counter: this.state.counter + this.props.increment,
});
```
-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:
+برای حل آن، شکل دوم تابع `setState()` را استفاده کنید که به جای یک شیء، یک تابع به عنوان ورودی میپذیرد. آن تابع هم state قبلی را به عنوان ورودی اول، و props مربوط به زمانی که تعییرات اعمال شدهاست را به عنوان ورودی دوم دریافت میکند.
```js
-// Correct
+// درست
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
```
-We used an [arrow function](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions) above, but it also works with regular functions:
+در بالا ما از [تابع arrow](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions) استفاده کردهایم، اما با تابع معمولی هم کار میکند:
```js
-// Correct
+// درست
this.setState(function(state, props) {
return {
counter: state.counter + props.increment
@@ -375,11 +378,11 @@ this.setState(function(state, props) {
});
```
-### State Updates are Merged {#state-updates-are-merged}
+### بهروز رسانیهای state ادغامشده هستند {#state-updates-are-merged}
-When you call `setState()`, React merges the object you provide into the current state.
+وقتی شما `setState()` را فرا میخوانید، ریاکت آن شیء را در state فعلی ادغام میکند.
-For example, your state may contain several independent variables:
+برای مثال، state شما ممکن است دارای چندین متغییر مستقل باشد:
```js{4,5}
constructor(props) {
@@ -391,7 +394,7 @@ For example, your state may contain several independent variables:
}
```
-Then you can update them independently with separate `setState()` calls:
+پس شما میتوانید آنها را جدا از هم، با فراخوانیهای مجزای `setState()`، بهروز رسانی کنید:
```js{4,10}
componentDidMount() {
@@ -408,28 +411,26 @@ Then you can update them independently with separate `setState()` calls:
});
}
```
+این ادغام سطحی است، بنابراین `this.setState({comments})` تاثیری روی `this.state.posts` ندارد، اما کاملا `this.state.comments` را جایگزین میکند.
-The merging is shallow, so `this.setState({comments})` leaves `this.state.posts` intact, but completely replaces `this.state.comments`.
-
-## The Data Flows Down {#the-data-flows-down}
+## داده به پایین جریان دارد {#the-data-flows-down}
-Neither parent nor child components can know if a certain component is stateful or stateless, and they shouldn't care whether it is defined as a function or a class.
+نه کامپوننت پدر و نه کامپوننت فرزند از اینکه یک کامپوننت مشخص دارای state است یا نه خبری ندارند و نباید برای آنها مهم باشد که به صورت تابع یا کلاس تعریف شدهاست.
-This is why state is often called local or encapsulated. It is not accessible to any component other than the one that owns and sets it.
+به همین دلیل است که اغلب state را داخلی یا کپسولهشده خطاب میکنند. به غیر از کامپوننتی که مالک آن است و با آن کار می کند، توسط هیچ کامپوننت دیگری قابل دسترسی نیست.
-A component may choose to pass its state down as props to its child components:
+یک کامپوننت ممکن است خودش انتخاب کند که state خود را به عنوان props به کامپوننتهای فرزند انتقال دهد.
```js
It is {this.state.date.toLocaleTimeString()}.
```
-
-This also works for user-defined components:
+همچنین برای کامپوننتهایی که توسط کاربر تعریف شدهاست، کار می کند.
```js
```
-The `FormattedDate` component would receive the `date` in its props and wouldn't know whether it came from the `Clock`'s state, from the `Clock`'s props, or was typed by hand:
+کامپوننت `FormattedDate` از props خود `date` را دریافت میکند و نخواهد فهمید که از state یا props `Clock` به دریافت کرده، یا با دست تایپ شدهاست.
```js
function FormattedDate(props) {
@@ -437,13 +438,13 @@ function FormattedDate(props) {
}
```
-[**Try it on CodePen**](https://codepen.io/gaearon/pen/zKRqNB?editors=0010)
+[**روی CodePen امتحان کنید**](https://codepen.io/gaearon/pen/zKRqNB?editors=0010)
-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.
+به این جریان داده عموما "یک طرفه" یا "بالا به پایین" گفته میشود. مالکیت هر state در دست یک کامپوننت مشخص است و هر داده یا UI که از آن state مشتق شدهباشد، فقط کامپوننتهای زیرین خود را در ساختار درختی تحت تاثیر قرار میدهد.
-If you imagine a component tree as a waterfall of props, each component's state is like an additional water source that joins it at an arbitrary point but also flows down.
+اگر یک درخت کامپوننت را به شکل آبشاری از props ها تصور کنید، state هر کامپوننت مانند منبعی اضافه از آب است که در نقطهای دلخواه به آن متصل و به پایین جریان پیدا میکند.
-To show that all components are truly isolated, we can create an `App` component that renders three ``s:
+برای نشاندادن اینکه تمام کامپوننتها واقعا ایزوله هستند، ما میتوانیم یک کامپوننت `App` بسازیم که سه کامپوننت `` را رندر میکند.
```js{4-6}
function App() {
@@ -462,8 +463,8 @@ ReactDOM.render(
);
```
-[**Try it on CodePen**](https://codepen.io/gaearon/pen/vXdGmd?editors=0010)
+[**روی CodePen امتحان کنید**](https://codepen.io/gaearon/pen/vXdGmd?editors=0010)
-Each `Clock` sets up its own timer and updates independently.
+هر `Clock` تایمر خودش را تنظیم و به طور مستقل بهروز رسانی میکند.
-In React apps, whether a component is stateful or stateless is considered an implementation detail of the component that may change over time. You can use stateless components inside stateful components, and vice versa.
+در برنامههای ریاکتی، اینکه یک کامپوننت دارای state هست یا نه، به جزئیات طراحی آن کامپوننت مربوط میشود که ممکن است در طول زمان تغییر کند. شما میتوانید کامپوننتهای بدون state را درون کامپوننت های دارای state استفاده کنید و همچنین برعکس.
diff --git a/content/languages.yml b/content/languages.yml
index ff0be2c1d..5e0958260 100644
--- a/content/languages.yml
+++ b/content/languages.yml
@@ -26,7 +26,7 @@
- name: German
translated_name: Deutsch
code: de
- status: 0
+ status: 1
- name: Greek
translated_name: Ελληνικά
code: el
@@ -50,7 +50,7 @@
- name: Hebrew
translated_name: עברית
code: he
- status: 0
+ status: 1
- name: Hindi
translated_name: हिन्दी
code: hi
@@ -78,7 +78,7 @@
- name: Korean
translated_name: 한국어
code: ko
- status: 0
+ status: 1
- name: Kurdish
translated_name: کوردی
code: ku
@@ -102,11 +102,11 @@
- name: Polish
translated_name: Polski
code: pl
- status: 0
+ status: 1
- name: Portuguese (Brazil)
translated_name: Português do Brasil
code: pt-br
- status: 1
+ status: 2
- name: Portuguese (Portugal)
translated_name: Português europeu
code: pt-pt
@@ -118,7 +118,7 @@
- name: Russian
translated_name: Русский
code: ru
- status: 1
+ status: 2
- name: Sinhala
translated_name: සිංහල
code: si
@@ -137,7 +137,7 @@
- name: Turkish
translated_name: Türkçe
code: tr
- status: 0
+ status: 1
- name: Ukrainian
translated_name: Українська
code: uk
diff --git a/src/theme.js b/src/theme.js
index f5fa76a12..4f8f3af89 100644
--- a/src/theme.js
+++ b/src/theme.js
@@ -89,6 +89,11 @@ const fonts = {
lineHeight: '65px',
fontWeight: 700,
+ [media.lessThan('small')]: {
+ overflowWrap: 'break-word',
+ wordBreak: 'break-word',
+ },
+
[media.lessThan('medium')]: {
fontSize: 40,
lineHeight: '45px',