From e4344bffa2a70543e7a93247242adc481f6fa31b Mon Sep 17 00:00:00 2001 From: Andrew Goldis Date: Sat, 9 Feb 2019 19:40:56 +1100 Subject: [PATCH 01/10] Add state and lifecyce translation --- content/docs/state-and-lifecycle.md | 179 ++++++++++++++-------------- 1 file changed, 89 insertions(+), 90 deletions(-) diff --git a/content/docs/state-and-lifecycle.md b/content/docs/state-and-lifecycle.md index dd5e2238c..dc9f3b559 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: Состояние и жизненный цикл 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) компонентов React. Подробная [документация 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). В разделе [Рендeринг элементов](/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**](http://codepen.io/gaearon/pen/gwoJZk?editors=0010) +[**Попробовать на CodePen**](http://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: +Начнем с инкапсуляции кода ответственного за вывод строки с текущим временем в функциональный компонент `Clock`: ```js{3-6,12} function Clock(props) { @@ -55,11 +55,11 @@ function tick() { setInterval(tick, 1000); ``` -[**Try it on CodePen**](http://codepen.io/gaearon/pen/dpdoYR?editors=0010) +[**Попробовать на CodePen**](http://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`, а это одно из ключевых требований. -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. +Для этого добавим так называемое "состояние" (state) в компонент `Clock`. -State is similar to props, but it is private and fully controlled by the component. +"Состояние" очень похоже на уже знакомые нам пропс (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), что класс-компоненты обладают дополнительными свойствами. Локальное "состояние" — это одно из таких свойств, которое доступно только класс-компнентам. -## Converting a Function to a Class {#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: +Давайте преобразуем функциональный компонент `Clock` в класс-компонент в 5 этапов: -1. Create an [ES6 class](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes), with the same name, that extends `React.Component`. +1. Создаем [ES6-класс](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Classes) с таким же именем, указываем `React.Component` в качестве родительского класса -2. Add a single empty method to it called `render()`. +2. Добавим в класс пустой метод `render()` -3. Move the body of the function into the `render()` method. +3. Перенесем тело функции в метод `render()` -4. Replace `props` with `this.props` in the `render()` body. +4. Заменим `props` на `this.props` в теле `render()` + +5. Удалим оставшееся пустое объявление функции -5. Delete the remaining empty function declaration. ```js class Clock extends React.Component { @@ -101,17 +102,18 @@ class Clock extends React.Component { } ``` -[**Try it on CodePen**](http://codepen.io/gaearon/pen/zKRGpo?editors=0010) +[**Попробовать на CodePen**](http://codepen.io/gaearon/pen/zKRGpo?editors=0010) + +`Clock` теперь определён как класс, а не функция. -`Clock` is now defined as a class rather than a function. -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. +Метод `render` будет вызываться каждый раз, когда происходит обновление. Так как мы отрисовываем `` в один и тот же DOM-контейнер, мы используем единственный экземпляр класса `Clock` - поэтому мы можем задействовать внутреннее состояние и хуки жизненного цикла. -## Adding Local State to a Class {#adding-local-state-to-a-class} +## Добавление локального состояния в класс {#adding-local-state-to-a-class} -We will move the `date` from props to state in three steps: +Переместим `date` из пропс в состояние в три этапа: -1) Replace `this.props.date` with `this.state.date` in the `render()` method: +1) Заменим `this.props.date` на `this.state.date` в методе `render()`: ```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/ru/docs/Web/JavaScript/Reference/Classes#Constructor), в котором укажем начальное состояние в переменной `this.state`: ```js{4} class Clock extends React.Component { @@ -146,7 +148,8 @@ class Clock extends React.Component { } ``` -Note how we pass `props` to the base constructor: +Обратите внимание, что мы передаём `props` базовому (родительскому) конструктору: + ```js{2} constructor(props) { @@ -155,9 +158,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` из элемента ``: ```js{2} ReactDOM.render( @@ -166,9 +169,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 +196,19 @@ ReactDOM.render( ); ``` -[**Try it on CodePen**](http://codepen.io/gaearon/pen/KgQpJd?editors=0010) +[**Попробовать на CodePen**](http://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} +## Добавление методов жизненного цикла в класс {#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. +Мы называем "монтированием" (установкой) первоначальный рендеринг `Clock` в DOM. Наша цель - [инициировать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) всякий раз, когда это происходит. -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) при каждой "размонтировке". -We can declare special methods on the component class to run some code when a component mounts and unmounts: +Давайте объявим специальные методы которые вызываются когда компонент устанавливается (монтируется) или удаляется (размонтируется): ```js{7-9,11-13} class Clock extends React.Component { @@ -233,9 +236,9 @@ class Clock extends React.Component { } ``` -These methods are called "lifecycle methods". +Эти методы называются "хуками (методами) жизненного цикла" (lifecycle methods). -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 +249,11 @@ The `componentDidMount()` method runs after the component output has been render } ``` -Note how we save the timer ID right on `this`. +Обратите внимание, что мы сохраняем ID таймера в `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). +В класс-компонентах `this.props` инициализируется самим React, так же как и `this.state` - у этих полей особое назначение. Однако, если вам нужно сохранить информацию, которая не является частью процесса обработки данных React, можно вручную добавить дополнительные поля в класс (например, ID таймера). -We will tear down the timer in the `componentWillUnmount()` lifecycle method: +Удалим таймер в хуке жизненного цикла `componentWillUnmount()`: ```js{2} componentWillUnmount() { @@ -258,9 +261,7 @@ 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. - -It will use `this.setState()` to schedule updates to the component local state: +Наконец, реализуем метод `tick()` - он запускается таймером каждую секунду и использует `this.setState()`, который планирует обновление внутреннего состояния компонента: ```js{18-22} class Clock extends React.Component { @@ -302,72 +303,72 @@ ReactDOM.render( ); ``` -[**Try it on CodePen**](http://codepen.io/gaearon/pen/amqdNA?editors=0010) +[**Попробовать на CodePen**](http://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()`, React вызывает конструктор компонента. `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) React вызывает метод `render()` компонента `Clock`. Таким образом React узнаёт, что отобразить на экране. Далее, React обновляет 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, React вызывает хук жизненного цикла `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()` ежесекундно. Часть метода - вызов `setState()` с объектом, содержащим текущее время в качестве аргумента - таким образом компонент `Clock` планирует обновление UI. Благодаря вызову `setState()` React знает, что состояние изменилось, и снова вызывает метод `render()`, чтобы узнать, что должно отображаться на экране. На этот раз `this.state.date` в методе `render()` будет другим, и поэтому вывод отрисованного компонента будет включать обновлённое время и React соответственно обновит 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, React вызывает хук жизненного цикла `componentWillUnmount()`, таким образом таймер будет остановлен и удален. -## Using State Correctly {#using-state-correctly} +## Правильное использование состояния {#using-state-correctly} -There are three things you should know about `setState()`. +Важно знать три детали о правильно применении `setState()`. -### Do Not Modify State Directly {#do-not-modify-state-directly} +### Не изменяйте состояние напрямую {#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'}); ``` -The only place where you can assign `this.state` is the constructor. +Конструктор — это единственное место, где вы можете присвоить значение `this.state` напрямую. -### State Updates May Be Asynchronous {#state-updates-may-be-asynchronous} +### Обновления состояния могут быть асинхронными {#state-updates-may-be-asynchronous} -React may batch multiple `setState()` calls into a single update for performance. +React может произвольно решить сгруппировать несколько вызовов `setState()` в одно обновление для улучшения производительности. -Because `this.props` and `this.state` may be updated asynchronously, you should not rely on their values for calculating the next state. +Поскольку `this.props` и `this.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()`, который принимает функцию, а не объект. Эта функция получит предыдущее состояние в качестве первого аргумента и значения пропс непосредственно во время обновления в качестве второго аргумента: ```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: +В данном примере мы использовали [стрелочную функцию](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Functions/Arrow_functions), но можно использовать и обычные функции: ```js -// Correct +// Правильно this.setState(function(state, props) { return { counter: state.counter + props.increment @@ -375,11 +376,11 @@ this.setState(function(state, props) { }); ``` -### State Updates are Merged {#state-updates-are-merged} +### Обновления состояния объединяются {#state-updates-are-merged} -When you call `setState()`, React merges the object you provide into the current state. +Когда мы вызываем `setState()`, React объеденит аргумент (новое состояние), c текущим состоянием. -For example, your state may contain several independent variables: +Например, состояние может состоять из нескольких независимых полей: ```js{4,5} constructor(props) { @@ -391,7 +392,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() { @@ -409,27 +410,25 @@ Then you can update them independently with separate `setState()` calls: } ``` -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} +Слияние состояния - поверхностное, поэтому вызов `this.setState({comments})` оставляет `this.state.posts` нетронутым, но полностью заменяет `this.state.comments`. -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. +## Однонаправленный поток данных {#the-data-flows-down} -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. +В иерархии компонентов, ни родительский, ни дочерние компоненты не знают задано (stateful) или нет (stateless) состояние определенного компонента. Так же им не важно, как был создан определенный компонент - с помощью функцим или класса. В связи с этим, состояние часто называют "локальным", "внутренним" или инкапсулированным. Оно недоступно для любого другого компонента, за исключением того, который им владеет и устанавливает его. -A component may choose to pass its state down as props to its child components: +Компонент может передать своё состояние вниз по дереву компонентов в виде пропс для его дочерних компонентов: ```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` получает `date` через пропс но не знает, является ли первоисточником состояние `Clock`, пропс `Clock` или оно было передано напрямую: ```js function FormattedDate(props) { @@ -437,13 +436,13 @@ function FormattedDate(props) { } ``` -[**Try it on CodePen**](http://codepen.io/gaearon/pen/zKRqNB?editors=0010) +[**Попробовать на CodePen**](http://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. +Этот процесс называется "сверху вниз" ("top-down") потоком данных или "однонаправленным" ("unidirectional") потоком данных. Состояние всегда принадлежит определённому компоненту, а любые производные этого состояния могут влиять только на компоненты, находящиеся «ниже» в дереве компонентов. -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. +Если представить иерархию компонентов как водопад пропс, то состояние каждого компонента похоже на дополнительный источник, который сливается с водопадом в произвольной точке, но также течёт вниз. -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 +461,8 @@ ReactDOM.render( ); ``` -[**Try it on CodePen**](http://codepen.io/gaearon/pen/vXdGmd?editors=0010) +[**Попробовать на CodePen**](http://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. +В React-приложениях, имеет ли компонент состояние или нет — это внутренняя деталь реализации компонента, которая может меняться со временем. Можно использовать компоненты без состояния в компонентах с состоянием, и наоборот. \ No newline at end of file From dfdb2df82a56ff11fdc75a549b8c6c7df121558c Mon Sep 17 00:00:00 2001 From: Andrew Goldis Date: Sun, 10 Feb 2019 11:28:10 +1100 Subject: [PATCH 02/10] Refine terms according to glossary --- content/docs/state-and-lifecycle.md | 48 ++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/content/docs/state-and-lifecycle.md b/content/docs/state-and-lifecycle.md index dc9f3b559..251710adc 100644 --- a/content/docs/state-and-lifecycle.md +++ b/content/docs/state-and-lifecycle.md @@ -8,9 +8,9 @@ prev: components-and-props.html next: handling-events.html --- -На этой странице представлена концепция "состояния" (state) и "жизненного цикла" (lifecycle) компонентов React. Подробная [документация API компонента доступна по ссылке](/docs/react-component.html) . +На этой странице представлена концепция "состояния" (state) и "жизненного цикла" (lifecycle) компонентов React. Подробная [справочнике API компонента доступна по ссылке](/docs/react-component.html) . -В качестве примера рассмотрим бегущие часы из [предыдущего раздела](/docs/rendering-elements.html#updating-the-rendered-element). В разделе [Рендeринг элементов](/docs/rendering-elements.html#rendering-an-element-into-the-dom) мы изучили лишь один способ обновления UI - вызвать `ReactDOM.render()` для изменения результата отрисовки (рендеринга): +В качестве примера рассмотрим бегущие часы из [предыдущего раздела](/docs/rendering-elements.html#updating-the-rendered-element). В разделе [Рендeринг элементов](/docs/rendering-elements.html#rendering-an-element-into-the-dom) мы изучили лишь один способ обновления UI - вызвать `ReactDOM.render()` для изменения результата рендера: ```js{8-11} function tick() { @@ -29,9 +29,9 @@ function tick() { setInterval(tick, 1000); ``` -[**Попробовать на CodePen**](http://codepen.io/gaearon/pen/gwoJZk?editors=0010) +[**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/gwoJZk?editors=0010) -В этом разделе мы узнаем, как инкаспулировать и обеспечить многократное использование компонента `Clock`. Компонент будет самостоятельно инициировать свой собственный таймер и будет самообновляться раз в секунду. +В этом разделе мы узнаем, как инкаспулировать и обеспечить многократное использование компонента `Clock`. Компонент самостоятельно создаст свой собственный таймер и будет самообновляться раз в секунду. Начнем с инкапсуляции кода ответственного за вывод строки с текущим временем в функциональный компонент `Clock`: @@ -55,11 +55,11 @@ function tick() { setInterval(tick, 1000); ``` -[**Попробовать на CodePen**](http://codepen.io/gaearon/pen/dpdoYR?editors=0010) +[**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/dpdoYR?editors=0010) -Обратите внимание, что инциирование таймера и ежесекундное обновление интерфейса не является внутренней деталью реализации компонента `Clock`, а это одно из ключевых требований. +Обратите внимание, что создание таймера и ежесекундное обновление интерфейса не является внутренней деталью реализации компонента `Clock`, а это одно из ключевых требований. -В идеале мы бы хотели имплементировать `Clock` таким образом, чтобы компонент сам себя обновлял: +В идеале мы бы хотели реализовать `Clock` таким образом, чтобы компонент сам себя обновлял: ```js{2} ReactDOM.render( @@ -72,11 +72,11 @@ ReactDOM.render( "Состояние" очень похоже на уже знакомые нам пропс (props), отличие в том, что состояние контролируется и доступно только конкретному компоненту. -Мы [уже упоминали](/docs/components-and-props.html#functional-and-class-components), что класс-компоненты обладают дополнительными свойствами. Локальное "состояние" — это одно из таких свойств, которое доступно только класс-компнентам. +Мы [уже упоминали](/docs/components-and-props.html#functional-and-class-components), что классовые компоненты обладают дополнительными свойствами. Локальное "состояние" — это одно из таких свойств, которое доступно только классовым компнентам. ## Преобразование функции в класс {#converting-a-function-to-a-class} -Давайте преобразуем функциональный компонент `Clock` в класс-компонент в 5 этапов: +Давайте преобразуем функциональный компонент `Clock` в классовый компонент в 5 этапов: 1. Создаем [ES6-класс](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Classes) с таким же именем, указываем `React.Component` в качестве родительского класса @@ -102,12 +102,12 @@ class Clock extends React.Component { } ``` -[**Попробовать на CodePen**](http://codepen.io/gaearon/pen/zKRGpo?editors=0010) +[**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/zKRGpo?editors=0010) `Clock` теперь определён как класс, а не функция. -Метод `render` будет вызываться каждый раз, когда происходит обновление. Так как мы отрисовываем `` в один и тот же DOM-контейнер, мы используем единственный экземпляр класса `Clock` - поэтому мы можем задействовать внутреннее состояние и хуки жизненного цикла. +Метод `render` будет вызываться каждый раз, когда происходит обновление. Так как мы рендерим `` в один и тот же DOM-контейнер, мы используем единственный экземпляр класса `Clock` - поэтому мы можем задействовать внутреннее состояние и хуки жизненного цикла. ## Добавление локального состояния в класс {#adding-local-state-to-a-class} @@ -158,7 +158,7 @@ class Clock extends React.Component { } ``` -Класс-компоненты всегда должны вызывать базовый конструктор с передачей ему `props`. +Классовые компоненты всегда должны вызывать базовый конструктор с передачей ему `props`. 3) Удалим проп `date` из элемента ``: @@ -196,15 +196,15 @@ ReactDOM.render( ); ``` -[**Попробовать на CodePen**](http://codepen.io/gaearon/pen/KgQpJd?editors=0010) +[**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/KgQpJd?editors=0010) -Следущий этап - добавить в `Clock` инициализацию собственного таймера с обновлением каждую секунду. +Следущий этап - добавить в `Clock` создание собственного таймера с обновлением каждую секунду. ## Добавление методов жизненного цикла в класс {#adding-lifecycle-methods-to-a-class} В приложениях с множеством компонентов очень важно освобождать используемые системные ресурсы при удалении компонентов. -Мы называем "монтированием" (установкой) первоначальный рендеринг `Clock` в DOM. Наша цель - [инициировать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) всякий раз, когда это происходит. +Мы называем "монтированием" (установкой) первоначальный рендеринг `Clock` в DOM. Наша цель - [создать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) всякий раз, когда это происходит. Каждый раз когда DOM-узел, созданный `Clock`, удаляется, просходит то, что мы называем "размонтирование". Учитывая важность сохранения ресурсов, мы [сбросим таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval) при каждой "размонтировке". @@ -238,7 +238,7 @@ class Clock extends React.Component { Эти методы называются "хуками (методами) жизненного цикла" (lifecycle methods). -Хук `componentDidMount()` запускается после того, как компонент отрендерился в DOM - это подходящее место для инициализирования таймера: +Хук `componentDidMount()` запускается после того, как компонент отрендерился в DOM - это подходящее место для создания таймера: ```js{2-5} componentDidMount() { @@ -251,7 +251,7 @@ class Clock extends React.Component { Обратите внимание, что мы сохраняем ID таймера в `this`. -В класс-компонентах `this.props` инициализируется самим React, так же как и `this.state` - у этих полей особое назначение. Однако, если вам нужно сохранить информацию, которая не является частью процесса обработки данных React, можно вручную добавить дополнительные поля в класс (например, ID таймера). +В классовых компонентах `this.props` создается самим React, так же как и `this.state` - у этих полей особое назначение. Однако, если вам нужно сохранить информацию, которая не является частью процесса обработки данных React, можно вручную добавить дополнительные поля в класс (например, ID таймера). Удалим таймер в хуке жизненного цикла `componentWillUnmount()`: @@ -303,7 +303,7 @@ ReactDOM.render( ); ``` -[**Попробовать на CodePen**](http://codepen.io/gaearon/pen/amqdNA?editors=0010) +[**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/amqdNA?editors=0010) Результат - часы обновляются каждую секунду. @@ -313,9 +313,9 @@ ReactDOM.render( 2) React вызывает метод `render()` компонента `Clock`. Таким образом React узнаёт, что отобразить на экране. Далее, React обновляет DOM так, чтобы он соответствовал выводу ренедера `Clock`. -3) Как только вывод рендера `Clock` вставлен в DOM, React вызывает хук жизненного цикла `componentDidMount()`. Внутри него компонент `Clock` указывает браузеру инициализировать таймер, который будет вызывать метод компонента `tick()` раз в секунду. +3) Как только вывод рендера `Clock` вставлен в DOM, React вызывает хук жизненного цикла `componentDidMount()`. Внутри него компонент `Clock` указывает браузеру создать таймер, который будет вызывать метод компонента `tick()` раз в секунду. -4) Таймер вызывает метод `tick()` ежесекундно. Часть метода - вызов `setState()` с объектом, содержащим текущее время в качестве аргумента - таким образом компонент `Clock` планирует обновление UI. Благодаря вызову `setState()` React знает, что состояние изменилось, и снова вызывает метод `render()`, чтобы узнать, что должно отображаться на экране. На этот раз `this.state.date` в методе `render()` будет другим, и поэтому вывод отрисованного компонента будет включать обновлённое время и React соответственно обновит DOM. +4) Таймер вызывает метод `tick()` ежесекундно. Часть метода - вызов `setState()` с объектом, содержащим текущее время в качестве аргумента - таким образом компонент `Clock` планирует обновление UI. Благодаря вызову `setState()` React знает, что состояние изменилось, и снова вызывает метод `render()`, чтобы узнать, что должно отображаться на экране. На этот раз `this.state.date` в методе `render()` будет другим, и поэтому ренедер компонента будет включать обновлённое время и React соответственно обновит DOM. 5) Если компонент `Clock` когда-либо удаляется из DOM, React вызывает хук жизненного цикла `componentWillUnmount()`, таким образом таймер будет остановлен и удален. @@ -325,7 +325,7 @@ ReactDOM.render( ### Не изменяйте состояние напрямую {#do-not-modify-state-directly} -В следующем примере повторной отрисовки компонента не происходит: +В следующем примере повторного рендера не происходит: ```js // Неправильно @@ -436,13 +436,13 @@ function FormattedDate(props) { } ``` -[**Попробовать на CodePen**](http://codepen.io/gaearon/pen/zKRqNB?editors=0010) +[**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/zKRqNB?editors=0010) Этот процесс называется "сверху вниз" ("top-down") потоком данных или "однонаправленным" ("unidirectional") потоком данных. Состояние всегда принадлежит определённому компоненту, а любые производные этого состояния могут влиять только на компоненты, находящиеся «ниже» в дереве компонентов. Если представить иерархию компонентов как водопад пропс, то состояние каждого компонента похоже на дополнительный источник, который сливается с водопадом в произвольной точке, но также течёт вниз. -Чтобы показать, что все компоненты действительно изолированы, создадим компонент `App`, который отрисовывает три компонента ``: +Чтобы показать, что все компоненты действительно изолированы, создадим компонент `App`, который рендерит три компонента ``: ```js{4-6} function App() { @@ -461,7 +461,7 @@ ReactDOM.render( ); ``` -[**Попробовать на CodePen**](http://codepen.io/gaearon/pen/vXdGmd?editors=0010) +[**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/vXdGmd?editors=0010) У каждого компонента `Clock` есть собственное состояние таймера, которое обновляется независимо от других компонентов. From 595657088d6a68efa290803446b5d640de351e37 Mon Sep 17 00:00:00 2001 From: Andrew Goldis Date: Sun, 10 Feb 2019 11:38:29 +1100 Subject: [PATCH 03/10] =?UTF-8?q?Replace=20"-"=20with=20"=E2=80=94"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content/docs/state-and-lifecycle.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/content/docs/state-and-lifecycle.md b/content/docs/state-and-lifecycle.md index 251710adc..3029c7fb1 100644 --- a/content/docs/state-and-lifecycle.md +++ b/content/docs/state-and-lifecycle.md @@ -10,7 +10,7 @@ next: handling-events.html На этой странице представлена концепция "состояния" (state) и "жизненного цикла" (lifecycle) компонентов React. Подробная [справочнике API компонента доступна по ссылке](/docs/react-component.html) . -В качестве примера рассмотрим бегущие часы из [предыдущего раздела](/docs/rendering-elements.html#updating-the-rendered-element). В разделе [Рендeринг элементов](/docs/rendering-elements.html#rendering-an-element-into-the-dom) мы изучили лишь один способ обновления UI - вызвать `ReactDOM.render()` для изменения результата рендера: +В качестве примера рассмотрим бегущие часы из [предыдущего раздела](/docs/rendering-elements.html#updating-the-rendered-element). В разделе [Рендeринг элементов](/docs/rendering-elements.html#rendering-an-element-into-the-dom) мы изучили лишь один способ обновления UI — вызвать `ReactDOM.render()` для изменения результата рендера: ```js{8-11} function tick() { @@ -107,7 +107,7 @@ class Clock extends React.Component { `Clock` теперь определён как класс, а не функция. -Метод `render` будет вызываться каждый раз, когда происходит обновление. Так как мы рендерим `` в один и тот же DOM-контейнер, мы используем единственный экземпляр класса `Clock` - поэтому мы можем задействовать внутреннее состояние и хуки жизненного цикла. +Метод `render` будет вызываться каждый раз, когда происходит обновление. Так как мы рендерим `` в один и тот же DOM-контейнер, мы используем единственный экземпляр класса `Clock` — поэтому мы можем задействовать внутреннее состояние и хуки жизненного цикла. ## Добавление локального состояния в класс {#adding-local-state-to-a-class} @@ -198,13 +198,13 @@ ReactDOM.render( [**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/KgQpJd?editors=0010) -Следущий этап - добавить в `Clock` создание собственного таймера с обновлением каждую секунду. +Следущий этап — добавить в `Clock` создание собственного таймера с обновлением каждую секунду. ## Добавление методов жизненного цикла в класс {#adding-lifecycle-methods-to-a-class} В приложениях с множеством компонентов очень важно освобождать используемые системные ресурсы при удалении компонентов. -Мы называем "монтированием" (установкой) первоначальный рендеринг `Clock` в DOM. Наша цель - [создать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) всякий раз, когда это происходит. +Мы называем "монтированием" (установкой) первоначальный рендеринг `Clock` в DOM. Наша цель — [создать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) всякий раз, когда это происходит. Каждый раз когда DOM-узел, созданный `Clock`, удаляется, просходит то, что мы называем "размонтирование". Учитывая важность сохранения ресурсов, мы [сбросим таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval) при каждой "размонтировке". @@ -238,7 +238,7 @@ class Clock extends React.Component { Эти методы называются "хуками (методами) жизненного цикла" (lifecycle methods). -Хук `componentDidMount()` запускается после того, как компонент отрендерился в DOM - это подходящее место для создания таймера: +Хук `componentDidMount()` запускается после того, как компонент отрендерился в DOM — это подходящее место для создания таймера: ```js{2-5} componentDidMount() { @@ -251,7 +251,7 @@ class Clock extends React.Component { Обратите внимание, что мы сохраняем ID таймера в `this`. -В классовых компонентах `this.props` создается самим React, так же как и `this.state` - у этих полей особое назначение. Однако, если вам нужно сохранить информацию, которая не является частью процесса обработки данных React, можно вручную добавить дополнительные поля в класс (например, ID таймера). +В классовых компонентах `this.props` создается самим React, так же как и `this.state` — у этих полей особое назначение. Однако, если вам нужно сохранить информацию, которая не является частью процесса обработки данных React, можно вручную добавить дополнительные поля в класс (например, ID таймера). Удалим таймер в хуке жизненного цикла `componentWillUnmount()`: @@ -261,7 +261,7 @@ class Clock extends React.Component { } ``` -Наконец, реализуем метод `tick()` - он запускается таймером каждую секунду и использует `this.setState()`, который планирует обновление внутреннего состояния компонента: +Наконец, реализуем метод `tick()` — он запускается таймером каждую секунду и использует `this.setState()`, который планирует обновление внутреннего состояния компонента: ```js{18-22} class Clock extends React.Component { @@ -305,7 +305,7 @@ ReactDOM.render( [**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/amqdNA?editors=0010) -Результат - часы обновляются каждую секунду. +Результат — часы обновляются каждую секунду. Давайте рассмотрим наше решение и разберем порядок, в котором вызываются методы: @@ -315,7 +315,7 @@ ReactDOM.render( 3) Как только вывод рендера `Clock` вставлен в DOM, React вызывает хук жизненного цикла `componentDidMount()`. Внутри него компонент `Clock` указывает браузеру создать таймер, который будет вызывать метод компонента `tick()` раз в секунду. -4) Таймер вызывает метод `tick()` ежесекундно. Часть метода - вызов `setState()` с объектом, содержащим текущее время в качестве аргумента - таким образом компонент `Clock` планирует обновление UI. Благодаря вызову `setState()` React знает, что состояние изменилось, и снова вызывает метод `render()`, чтобы узнать, что должно отображаться на экране. На этот раз `this.state.date` в методе `render()` будет другим, и поэтому ренедер компонента будет включать обновлённое время и React соответственно обновит DOM. +4) Таймер вызывает метод `tick()` ежесекундно. Часть метода — вызов `setState()` с объектом, содержащим текущее время в качестве аргумента — таким образом компонент `Clock` планирует обновление UI. Благодаря вызову `setState()` React знает, что состояние изменилось, и снова вызывает метод `render()`, чтобы узнать, что должно отображаться на экране. На этот раз `this.state.date` в методе `render()` будет другим, и поэтому ренедер компонента будет включать обновлённое время и React соответственно обновит DOM. 5) Если компонент `Clock` когда-либо удаляется из DOM, React вызывает хук жизненного цикла `componentWillUnmount()`, таким образом таймер будет остановлен и удален. @@ -410,11 +410,11 @@ this.setState(function(state, props) { } ``` -Слияние состояния - поверхностное, поэтому вызов `this.setState({comments})` оставляет `this.state.posts` нетронутым, но полностью заменяет `this.state.comments`. +Слияние состояния — поверхностное, поэтому вызов `this.setState({comments})` оставляет `this.state.posts` нетронутым, но полностью заменяет `this.state.comments`. ## Однонаправленный поток данных {#the-data-flows-down} -В иерархии компонентов, ни родительский, ни дочерние компоненты не знают задано (stateful) или нет (stateless) состояние определенного компонента. Так же им не важно, как был создан определенный компонент - с помощью функцим или класса. В связи с этим, состояние часто называют "локальным", "внутренним" или инкапсулированным. Оно недоступно для любого другого компонента, за исключением того, который им владеет и устанавливает его. +В иерархии компонентов, ни родительский, ни дочерние компоненты не знают задано (stateful) или нет (stateless) состояние определенного компонента. Так же им не важно, как был создан определенный компонент — с помощью функцим или класса. В связи с этим, состояние часто называют "локальным", "внутренним" или инкапсулированным. Оно недоступно для любого другого компонента, за исключением того, который им владеет и устанавливает его. Компонент может передать своё состояние вниз по дереву компонентов в виде пропс для его дочерних компонентов: From c3708cc64badfd7847f781f3fc968246989cc848 Mon Sep 17 00:00:00 2001 From: Andrew Goldis Date: Sun, 10 Feb 2019 12:42:53 +1100 Subject: [PATCH 04/10] Change navigation title --- content/docs/nav.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/nav.yml b/content/docs/nav.yml index 4d4a7571f..00dfe144e 100644 --- a/content/docs/nav.yml +++ b/content/docs/nav.yml @@ -20,7 +20,7 @@ - id: components-and-props title: Components and Props - id: state-and-lifecycle - title: State and Lifecycle + title: Состояние и жизненный цикл - id: handling-events title: Handling Events - id: conditional-rendering From 9043f0052fa773f9da9e6ea9a724f779e14bad96 Mon Sep 17 00:00:00 2001 From: Andrew Goldis Date: Sun, 10 Feb 2019 13:52:45 +1100 Subject: [PATCH 05/10] Reduce usage of deverbative subjects, use dictionary terms --- content/docs/state-and-lifecycle.md | 71 ++++++++++++++--------------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/content/docs/state-and-lifecycle.md b/content/docs/state-and-lifecycle.md index 3029c7fb1..0fca5f7fa 100644 --- a/content/docs/state-and-lifecycle.md +++ b/content/docs/state-and-lifecycle.md @@ -8,9 +8,9 @@ prev: components-and-props.html next: handling-events.html --- -На этой странице представлена концепция "состояния" (state) и "жизненного цикла" (lifecycle) компонентов React. Подробная [справочнике API компонента доступна по ссылке](/docs/react-component.html) . +На этой странице представлены понятия «состояния» (state) и «жизненного цикла» (lifecycle) React-компонентов. Подробный [справочник API компонентов доступен по ссылке](/docs/react-component.html) . -В качестве примера рассмотрим бегущие часы из [предыдущего раздела](/docs/rendering-elements.html#updating-the-rendered-element). В разделе [Рендeринг элементов](/docs/rendering-elements.html#rendering-an-element-into-the-dom) мы изучили лишь один способ обновления UI — вызвать `ReactDOM.render()` для изменения результата рендера: +В качестве примера рассмотрим бегущие часы из [предыдущего раздела](/docs/rendering-elements.html#updating-the-rendered-element). В главе [Рендeринг элементов](/docs/rendering-elements.html#rendering-an-element-into-the-dom) мы изучили лишь один способ обновления UI — вызвать `ReactDOM.render()` для изменения результата рендера: ```js{8-11} function tick() { @@ -31,9 +31,9 @@ setInterval(tick, 1000); [**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/gwoJZk?editors=0010) -В этом разделе мы узнаем, как инкаспулировать и обеспечить многократное использование компонента `Clock`. Компонент самостоятельно создаст свой собственный таймер и будет самообновляться раз в секунду. +В этой главе мы узнаем, как инкаспулировать и обеспечить многократное использование компонента `Clock`. Компонент самостоятельно создаст свой собственный таймер и будет самообновляться раз в секунду. -Начнем с инкапсуляции кода ответственного за вывод строки с текущим временем в функциональный компонент `Clock`: +Для начала, извлечём компонент, показывающий время: ```js{3-6,12} function Clock(props) { @@ -57,7 +57,7 @@ setInterval(tick, 1000); [**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/dpdoYR?editors=0010) -Обратите внимание, что создание таймера и ежесекундное обновление интерфейса не является внутренней деталью реализации компонента `Clock`, а это одно из ключевых требований. +Проблема в том, что компонент `Clock` не обновляет себя каждую секунду автоматически. Хотелось бы спрятать логику, управляющую таймером, внутри самого компонента `Clock`. В идеале мы бы хотели реализовать `Clock` таким образом, чтобы компонент сам себя обновлял: @@ -68,15 +68,15 @@ ReactDOM.render( ); ``` -Для этого добавим так называемое "состояние" (state) в компонент `Clock`. +Для этого добавим так называемое «состояние» (state) в компонент `Clock`. -"Состояние" очень похоже на уже знакомые нам пропс (props), отличие в том, что состояние контролируется и доступно только конкретному компоненту. +«Состояние» очень похоже на уже знакомые нам пропсы (props), отличие в том, что состояние контролируется и доступно только конкретному компоненту. -Мы [уже упоминали](/docs/components-and-props.html#functional-and-class-components), что классовые компоненты обладают дополнительными свойствами. Локальное "состояние" — это одно из таких свойств, которое доступно только классовым компнентам. +Мы [уже упоминали](/docs/components-and-props.html#functional-and-class-components), что классовые компоненты обладают дополнительными способностями. Локальное «состояние» — одна из таких способностей, которое доступно только классовым компнентам. ## Преобразование функции в класс {#converting-a-function-to-a-class} -Давайте преобразуем функциональный компонент `Clock` в классовый компонент в 5 этапов: +Давайте преобразуем функциональный компонент `Clock` в классовый компонент за 5 шагов: 1. Создаем [ES6-класс](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Classes) с таким же именем, указываем `React.Component` в качестве родительского класса @@ -104,14 +104,13 @@ class Clock extends React.Component { [**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/zKRGpo?editors=0010) -`Clock` теперь определён как класс, а не функция. +Теперь `Clock` определён как класс, а не функция. +Метод `render` будет вызываться каждый раз, когда происходит обновление. Так как мы рендерим `` в один и тот же DOM-контейнер, мы используем единственный экземпляр класса `Clock` — поэтому мы можем задействовать внутреннее состояние и методы жизненного цикла. -Метод `render` будет вызываться каждый раз, когда происходит обновление. Так как мы рендерим `` в один и тот же DOM-контейнер, мы используем единственный экземпляр класса `Clock` — поэтому мы можем задействовать внутреннее состояние и хуки жизненного цикла. +## Добавим локальное состояния в класс {#adding-local-state-to-a-class} -## Добавление локального состояния в класс {#adding-local-state-to-a-class} - -Переместим `date` из пропс в состояние в три этапа: +Переместим `date` из пропсов в состояние в три этапа: 1) Заменим `this.props.date` на `this.state.date` в методе `render()`: @@ -198,17 +197,17 @@ ReactDOM.render( [**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/KgQpJd?editors=0010) -Следущий этап — добавить в `Clock` создание собственного таймера с обновлением каждую секунду. +Следущий этап — создать собственный таймер внутри `Clock` и обновлять компонент каждую секунду. -## Добавление методов жизненного цикла в класс {#adding-lifecycle-methods-to-a-class} +## Добавим методы жизненного цикла в класс {#adding-lifecycle-methods-to-a-class} -В приложениях с множеством компонентов очень важно освобождать используемые системные ресурсы при удалении компонентов. +В приложениях с множеством компонентов очень важно освобождать используемые системные ресурсы когда компоненты удаляются. -Мы называем "монтированием" (установкой) первоначальный рендеринг `Clock` в DOM. Наша цель — [создать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) всякий раз, когда это происходит. +Первоначальный рендеринг компонента в DOM называется «монтирование» (установка). Наша цель — [создавать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) всякий раз, когда это происходит. -Каждый раз когда DOM-узел, созданный `Clock`, удаляется, просходит то, что мы называем "размонтирование". Учитывая важность сохранения ресурсов, мы [сбросим таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval) при каждой "размонтировке". +Каждый раз когда DOM-узел, созданный компонентом, удаляется, просходит то, что мы называем «размонтирование». Учитывая важность сохранения ресурсов, мы [сбросим таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval) при каждой «размонтировке». -Давайте объявим специальные методы которые вызываются когда компонент устанавливается (монтируется) или удаляется (размонтируется): +Давайте объявим специальные методы - когда компонент устанавливается (монтируется) или удаляется (размонтируется) он будет их вызывать: ```js{7-9,11-13} class Clock extends React.Component { @@ -236,9 +235,9 @@ class Clock extends React.Component { } ``` -Эти методы называются "хуками (методами) жизненного цикла" (lifecycle methods). +Эти методы называются «методами жизненного цикла» (lifecycle methods). -Хук `componentDidMount()` запускается после того, как компонент отрендерился в DOM — это подходящее место для создания таймера: +Метод `componentDidMount()` запускается после того, как компонент отрендерился в DOM — здесь мы и созданим таймер: ```js{2-5} componentDidMount() { @@ -251,9 +250,9 @@ class Clock extends React.Component { Обратите внимание, что мы сохраняем ID таймера в `this`. -В классовых компонентах `this.props` создается самим React, так же как и `this.state` — у этих полей особое назначение. Однако, если вам нужно сохранить информацию, которая не является частью процесса обработки данных React, можно вручную добавить дополнительные поля в класс (например, ID таймера). +В классовых компонентах React сам создает`this.props`, у этого поля так же как и у `this.state` особое назначение. Однако, если вам нужно сохранить информацию, которая не является частью процесса обработки данных React, можете вручную добавить дополнительные поля в класс (например, ID таймера). -Удалим таймер в хуке жизненного цикла `componentWillUnmount()`: +Удалим таймер в методе жизненного цикла `componentWillUnmount()`: ```js{2} componentWillUnmount() { @@ -309,15 +308,15 @@ ReactDOM.render( Давайте рассмотрим наше решение и разберем порядок, в котором вызываются методы: -1) Когда мы передаём `` в `ReactDOM.render()`, React вызывает конструктор компонента. `Clock` должен отображать текущее время, поэтому мы задаем начальное состояние `this.state` объектом, включающим текущее время. +1) Когда мы передаём `` в `ReactDOM.render()`, React вызывает конструктор компонента. `Clock` должен отображать текущее время, поэтому мы задаем начальное состояние `this.state` объектом с текущим временем. 2) React вызывает метод `render()` компонента `Clock`. Таким образом React узнаёт, что отобразить на экране. Далее, React обновляет DOM так, чтобы он соответствовал выводу ренедера `Clock`. -3) Как только вывод рендера `Clock` вставлен в DOM, React вызывает хук жизненного цикла `componentDidMount()`. Внутри него компонент `Clock` указывает браузеру создать таймер, который будет вызывать метод компонента `tick()` раз в секунду. +3) Как только вывод рендера `Clock` вставлен в DOM, React вызывает метод жизненного цикла `componentDidMount()`. Внутри него компонент `Clock` указывает браузеру создать таймер, который будет вызывать `tick()` раз в секунду. -4) Таймер вызывает метод `tick()` ежесекундно. Часть метода — вызов `setState()` с объектом, содержащим текущее время в качестве аргумента — таким образом компонент `Clock` планирует обновление UI. Благодаря вызову `setState()` React знает, что состояние изменилось, и снова вызывает метод `render()`, чтобы узнать, что должно отображаться на экране. На этот раз `this.state.date` в методе `render()` будет другим, и поэтому ренедер компонента будет включать обновлённое время и React соответственно обновит DOM. +4) Таймер вызывает метод `tick()` ежесекундно. Часть метода — вызов `setState()` с объектом текущего времени — таким образом компонент `Clock` планирует обновление UI. Благодаря вызову `setState()` React знает, что состояние изменилось, и снова вызывает метод `render()`, чтобы узнать, что должно отображаться на экране. На этот раз `this.state.date` в методе `render()` будет другим, ренедер компонента будет включать обновлённое время и React обновит DOM соответственно. -5) Если компонент `Clock` когда-либо удаляется из DOM, React вызывает хук жизненного цикла `componentWillUnmount()`, таким образом таймер будет остановлен и удален. +5) Если компонент `Clock` когда-либо удаляется из DOM, React вызывает метод жизненного цикла `componentWillUnmount()`, таким образом таймер будет остановлен и удален. ## Правильное использование состояния {#using-state-correctly} @@ -378,7 +377,7 @@ this.setState(function(state, props) { ### Обновления состояния объединяются {#state-updates-are-merged} -Когда мы вызываем `setState()`, React объеденит аргумент (новое состояние), c текущим состоянием. +Когда мы вызываем `setState()`, React объеденит аргумент (новое состояние) c текущим состоянием. Например, состояние может состоять из нескольких независимых полей: @@ -392,7 +391,7 @@ this.setState(function(state, props) { } ``` -Можете их независимо обновлять с помощью отдельных вызовов `setState()`: +Их можно обновлять по отдельности с помощью отдельных вызовов `setState()`: ```js{4,10} componentDidMount() { @@ -410,13 +409,13 @@ this.setState(function(state, props) { } ``` -Слияние состояния — поверхностное, поэтому вызов `this.setState({comments})` оставляет `this.state.posts` нетронутым, но полностью заменяет `this.state.comments`. +Состояния объединяются поверхностно, поэтому вызов `this.setState({comments})` оставляет `this.state.posts` нетронутым, но полностью заменяет `this.state.comments`. ## Однонаправленный поток данных {#the-data-flows-down} -В иерархии компонентов, ни родительский, ни дочерние компоненты не знают задано (stateful) или нет (stateless) состояние определенного компонента. Так же им не важно, как был создан определенный компонент — с помощью функцим или класса. В связи с этим, состояние часто называют "локальным", "внутренним" или инкапсулированным. Оно недоступно для любого другого компонента, за исключением того, который им владеет и устанавливает его. +В иерархии компонентов, ни родительский, ни дочерние компоненты не знают с состоянием (stateful) другие компоненты или без состояния (stateless). Так же не важно, как был создан определенный компонент — с помощью функции или класса. Поэтому, состояние часто называют «локальным», «внутренним» или инкапсулированным. Оно доступно только для самого компонента и скрыто от других. -Компонент может передать своё состояние вниз по дереву компонентов в виде пропс для его дочерних компонентов: +Компонент может передать своё состояние вниз по дереву в виде пропсов дочерних компонентов: ```js

It is {this.state.date.toLocaleTimeString()}.

@@ -428,7 +427,7 @@ this.setState(function(state, props) { ``` -Компонент `FormattedDate` получает `date` через пропс но не знает, является ли первоисточником состояние `Clock`, пропс `Clock` или оно было передано напрямую: +Компонент `FormattedDate` получает `date` через пропсы но не знает, является ли первоисточником состояние `Clock`, пропс `Clock` или оно было передано напрямую: ```js function FormattedDate(props) { @@ -438,9 +437,9 @@ function FormattedDate(props) { [**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/zKRqNB?editors=0010) -Этот процесс называется "сверху вниз" ("top-down") потоком данных или "однонаправленным" ("unidirectional") потоком данных. Состояние всегда принадлежит определённому компоненту, а любые производные этого состояния могут влиять только на компоненты, находящиеся «ниже» в дереве компонентов. +Этот процесс называется «нисходящим» ("top-down") или «однонаправленным» ("unidirectional") потоком данных. Состояние всегда принадлежит определённому компоненту, а любые производные этого состояния могут влиять только на компоненты, находящиеся «ниже» в дереве компонентов. -Если представить иерархию компонентов как водопад пропс, то состояние каждого компонента похоже на дополнительный источник, который сливается с водопадом в произвольной точке, но также течёт вниз. +Если представить иерархию компонентов как водопад пропсов, то состояние каждого компонента похоже на дополнительный источник, который сливается с водопадом в произвольной точке, но также течёт вниз. Чтобы показать, что все компоненты действительно изолированы, создадим компонент `App`, который рендерит три компонента ``: From 7769f5489731a6e99826e14e3fb6c9fc3820c016 Mon Sep 17 00:00:00 2001 From: Andrew Goldis Date: Mon, 11 Feb 2019 10:09:30 +1100 Subject: [PATCH 06/10] Fix grammar errors, translate code --- content/docs/state-and-lifecycle.md | 50 ++++++++++++++--------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/content/docs/state-and-lifecycle.md b/content/docs/state-and-lifecycle.md index 0fca5f7fa..abe40296c 100644 --- a/content/docs/state-and-lifecycle.md +++ b/content/docs/state-and-lifecycle.md @@ -16,8 +16,8 @@ next: handling-events.html function tick() { const element = (
-

Hello, world!

-

It is {new Date().toLocaleTimeString()}.

+

Привет, мир!

+

Сейчас {new Date().toLocaleTimeString()}.

); ReactDOM.render( @@ -31,7 +31,7 @@ setInterval(tick, 1000); [**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/gwoJZk?editors=0010) -В этой главе мы узнаем, как инкаспулировать и обеспечить многократное использование компонента `Clock`. Компонент самостоятельно создаст свой собственный таймер и будет самообновляться раз в секунду. +В этой главе мы узнаем, как инкапсулировать и обеспечить многократное использование компонента `Clock`. Компонент самостоятельно создаст свой собственный таймер и будет самообновляться раз в секунду. Для начала, извлечём компонент, показывающий время: @@ -39,8 +39,8 @@ setInterval(tick, 1000); function Clock(props) { return (
-

Hello, world!

-

It is {props.date.toLocaleTimeString()}.

+

Привет, мир!

+

Сейчас {props.date.toLocaleTimeString()}.

); } @@ -94,8 +94,8 @@ class Clock extends React.Component { render() { return (
-

Hello, world!

-

It is {this.props.date.toLocaleTimeString()}.

+

Привет, мир!

+

Сейчас {this.props.date.toLocaleTimeString()}.

); } @@ -119,8 +119,8 @@ class Clock extends React.Component { render() { return (
-

Hello, world!

-

It is {this.state.date.toLocaleTimeString()}.

+

Привет, мир!

+

Сейчас {this.state.date.toLocaleTimeString()}.

); } @@ -139,8 +139,8 @@ class Clock extends React.Component { render() { return (
-

Hello, world!

-

It is {this.state.date.toLocaleTimeString()}.

+

Привет, мир!

+

Сейчас {this.state.date.toLocaleTimeString()}.

); } @@ -182,8 +182,8 @@ class Clock extends React.Component { render() { return (
-

Hello, world!

-

It is {this.state.date.toLocaleTimeString()}.

+

Привет, мир!

+

Сейчас {this.state.date.toLocaleTimeString()}.

); } @@ -227,8 +227,8 @@ class Clock extends React.Component { render() { return (
-

Hello, world!

-

It is {this.state.date.toLocaleTimeString()}.

+

Привет, мир!

+

Сейчас {this.state.date.toLocaleTimeString()}.

); } @@ -237,7 +237,7 @@ class Clock extends React.Component { Эти методы называются «методами жизненного цикла» (lifecycle methods). -Метод `componentDidMount()` запускается после того, как компонент отрендерился в DOM — здесь мы и созданим таймер: +Метод `componentDidMount()` запускается после того, как компонент отрендерился в DOM — здесь мы и создадим таймер: ```js{2-5} componentDidMount() { @@ -250,7 +250,7 @@ class Clock extends React.Component { Обратите внимание, что мы сохраняем ID таймера в `this`. -В классовых компонентах React сам создает`this.props`, у этого поля так же как и у `this.state` особое назначение. Однако, если вам нужно сохранить информацию, которая не является частью процесса обработки данных React, можете вручную добавить дополнительные поля в класс (например, ID таймера). +В классовых компонентах React сам создает `this.props`, у этого поля так же как и у `this.state` особое назначение. Однако, если вам нужно сохранить информацию, которая не является частью процесса обработки данных React, можете вручную добавить дополнительные поля в класс (например, ID таймера). Удалим таймер в методе жизненного цикла `componentWillUnmount()`: @@ -289,8 +289,8 @@ class Clock extends React.Component { render() { return (
-

Hello, world!

-

It is {this.state.date.toLocaleTimeString()}.

+

Привет, мир!

+

Сейчас {this.state.date.toLocaleTimeString()}.

); } @@ -314,11 +314,11 @@ ReactDOM.render( 3) Как только вывод рендера `Clock` вставлен в DOM, React вызывает метод жизненного цикла `componentDidMount()`. Внутри него компонент `Clock` указывает браузеру создать таймер, который будет вызывать `tick()` раз в секунду. -4) Таймер вызывает метод `tick()` ежесекундно. Часть метода — вызов `setState()` с объектом текущего времени — таким образом компонент `Clock` планирует обновление UI. Благодаря вызову `setState()` React знает, что состояние изменилось, и снова вызывает метод `render()`, чтобы узнать, что должно отображаться на экране. На этот раз `this.state.date` в методе `render()` будет другим, ренедер компонента будет включать обновлённое время и React обновит DOM соответственно. +4) Таймер вызывает метод `tick()` ежесекундно. Часть метода — вызов `setState()` с объектом текущего времени — таким образом компонент `Clock` планирует обновление UI. Благодаря вызову `setState()` React знает, что состояние изменилось, и снова вызывает метод `render()`, чтобы узнать, что должно отображаться на экране. На этот раз `this.state.date` в методе `render()` будет другим, рендер компонента будет включать обновлённое время и React обновит DOM соответственно. 5) Если компонент `Clock` когда-либо удаляется из DOM, React вызывает метод жизненного цикла `componentWillUnmount()`, таким образом таймер будет остановлен и удален. -## Правильное использование состояния {#using-state-correctly} +## Как правильно использовать состояние {#using-state-correctly} Важно знать три детали о правильно применении `setState()`. @@ -377,7 +377,7 @@ this.setState(function(state, props) { ### Обновления состояния объединяются {#state-updates-are-merged} -Когда мы вызываем `setState()`, React объеденит аргумент (новое состояние) c текущим состоянием. +Когда мы вызываем `setState()`, React объединит аргумент (новое состояние) c текущим состоянием. Например, состояние может состоять из нескольких независимых полей: @@ -413,12 +413,12 @@ this.setState(function(state, props) { ## Однонаправленный поток данных {#the-data-flows-down} -В иерархии компонентов, ни родительский, ни дочерние компоненты не знают с состоянием (stateful) другие компоненты или без состояния (stateless). Так же не важно, как был создан определенный компонент — с помощью функции или класса. Поэтому, состояние часто называют «локальным», «внутренним» или инкапсулированным. Оно доступно только для самого компонента и скрыто от других. +В иерархии компонентов, ни родительский, ни дочерние компоненты не знают с состоянием (stateful) другие компоненты или без состояния (stateless). Также не важно, как был создан определенный компонент — с помощью функции или класса. Поэтому, состояние часто называют «локальным», «внутренним» или инкапсулированным. Оно доступно только для самого компонента и скрыто от других. Компонент может передать своё состояние вниз по дереву в виде пропсов дочерних компонентов: ```js -

It is {this.state.date.toLocaleTimeString()}.

+

Сейчас {this.state.date.toLocaleTimeString()}.

``` Это также верно для пользовательских компонентов: @@ -431,7 +431,7 @@ this.setState(function(state, props) { ```js function FormattedDate(props) { - return

It is {props.date.toLocaleTimeString()}.

; + return

Сейчас {props.date.toLocaleTimeString()}.

; } ``` From ce67c66f848ddb836789a110edf3ffd398435783 Mon Sep 17 00:00:00 2001 From: Andrew Goldis Date: Mon, 11 Feb 2019 10:21:04 +1100 Subject: [PATCH 07/10] Fine-tune "ticking clock" translation --- content/docs/state-and-lifecycle.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/state-and-lifecycle.md b/content/docs/state-and-lifecycle.md index abe40296c..46499303f 100644 --- a/content/docs/state-and-lifecycle.md +++ b/content/docs/state-and-lifecycle.md @@ -10,7 +10,7 @@ next: handling-events.html На этой странице представлены понятия «состояния» (state) и «жизненного цикла» (lifecycle) React-компонентов. Подробный [справочник API компонентов доступен по ссылке](/docs/react-component.html) . -В качестве примера рассмотрим бегущие часы из [предыдущего раздела](/docs/rendering-elements.html#updating-the-rendered-element). В главе [Рендeринг элементов](/docs/rendering-elements.html#rendering-an-element-into-the-dom) мы изучили лишь один способ обновления UI — вызвать `ReactDOM.render()` для изменения результата рендера: +В качестве примера рассмотрим идущие часы из [предыдущего раздела](/docs/rendering-elements.html#updating-the-rendered-element). В главе [Рендeринг элементов](/docs/rendering-elements.html#rendering-an-element-into-the-dom) мы изучили лишь один способ обновления UI — вызвать `ReactDOM.render()` для изменения результата рендера: ```js{8-11} function tick() { From d3e74e81f7addabdd73b0b5b1bf6032eb5d5580e Mon Sep 17 00:00:00 2001 From: Andrew Goldis Date: Mon, 11 Feb 2019 14:44:28 +1100 Subject: [PATCH 08/10] Break down complex sentences and fix typos --- content/docs/state-and-lifecycle.md | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/content/docs/state-and-lifecycle.md b/content/docs/state-and-lifecycle.md index 46499303f..2b7d95a0b 100644 --- a/content/docs/state-and-lifecycle.md +++ b/content/docs/state-and-lifecycle.md @@ -8,7 +8,7 @@ prev: components-and-props.html next: handling-events.html --- -На этой странице представлены понятия «состояния» (state) и «жизненного цикла» (lifecycle) React-компонентов. Подробный [справочник API компонентов доступен по ссылке](/docs/react-component.html) . +На этой странице представлены понятия «состояние» (state) и «жизненный цикл» (lifecycle) React-компонентов. Подробный [справочник API компонентов находится по этой ссылке](/docs/react-component.html). В качестве примера рассмотрим идущие часы из [предыдущего раздела](/docs/rendering-elements.html#updating-the-rendered-element). В главе [Рендeринг элементов](/docs/rendering-elements.html#rendering-an-element-into-the-dom) мы изучили лишь один способ обновления UI — вызвать `ReactDOM.render()` для изменения результата рендера: @@ -157,7 +157,7 @@ class Clock extends React.Component { } ``` -Классовые компоненты всегда должны вызывать базовый конструктор с передачей ему `props`. +Классовые компоненты всегда должны вызывать базовый конструктор с агрументом `props`. 3) Удалим проп `date` из элемента ``: @@ -197,17 +197,17 @@ ReactDOM.render( [**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/KgQpJd?editors=0010) -Следущий этап — создать собственный таймер внутри `Clock` и обновлять компонент каждую секунду. +Теперь осталось только создать собственный таймер внутри `Clock` и обновлять компонент каждую секунду. ## Добавим методы жизненного цикла в класс {#adding-lifecycle-methods-to-a-class} В приложениях с множеством компонентов очень важно освобождать используемые системные ресурсы когда компоненты удаляются. -Первоначальный рендеринг компонента в DOM называется «монтирование» (установка). Наша цель — [создавать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) всякий раз, когда это происходит. +Первоначальный рендеринг компонента в DOM называется «монтирование» (установка). Нам нужно [создавать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) всякий раз, когда это происходит. -Каждый раз когда DOM-узел, созданный компонентом, удаляется, просходит то, что мы называем «размонтирование». Учитывая важность сохранения ресурсов, мы [сбросим таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval) при каждой «размонтировке». +Каждый раз когда DOM-узел, созданный компонентом, удаляется, просходит то, что мы называем «размонтирование». Учитывая важность сохранения ресурсов, мы будем [сбрасывать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval) при каждой «размонтировке». -Давайте объявим специальные методы - когда компонент устанавливается (монтируется) или удаляется (размонтируется) он будет их вызывать: +Объявим специальные методы, которые компонент будет вызывать при монтировнии и размонтировании: ```js{7-9,11-13} class Clock extends React.Component { @@ -250,7 +250,7 @@ class Clock extends React.Component { Обратите внимание, что мы сохраняем ID таймера в `this`. -В классовых компонентах React сам создает `this.props`, у этого поля так же как и у `this.state` особое назначение. Однако, если вам нужно сохранить информацию, которая не является частью процесса обработки данных React, можете вручную добавить дополнительные поля в класс (например, ID таймера). +В классовых компонентах у полей `this.props` и `this.state` особое назначение, более того, React сам создает `this.props`. Вы можете вручную добавить новые поля (например, ID таймера), если нужно сохранить дополнительную информацию о классе. Удалим таймер в методе жизненного цикла `componentWillUnmount()`: @@ -260,7 +260,9 @@ class Clock extends React.Component { } ``` -Наконец, реализуем метод `tick()` — он запускается таймером каждую секунду и использует `this.setState()`, который планирует обновление внутреннего состояния компонента: +Наконец, реализуем метод `tick()`. Он запускается таймером каждую секунду и использует `this.setState()`. + +`this.setState()` планирует обновление внутреннего состояния компонента: ```js{18-22} class Clock extends React.Component { @@ -304,7 +306,7 @@ ReactDOM.render( [**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/amqdNA?editors=0010) -Результат — часы обновляются каждую секунду. +Теперь часы обновляются каждую секунду. Давайте рассмотрим наше решение и разберем порядок, в котором вызываются методы: @@ -320,7 +322,7 @@ ReactDOM.render( ## Как правильно использовать состояние {#using-state-correctly} -Важно знать три детали о правильно применении `setState()`. +Важно знать три детали о правильном применении `setState()`. ### Не изменяйте состояние напрямую {#do-not-modify-state-directly} @@ -355,7 +357,7 @@ this.setState({ }); ``` -Правильно будет использовать второй вариант вызова `setState()`, который принимает функцию, а не объект. Эта функция получит предыдущее состояние в качестве первого аргумента и значения пропс непосредственно во время обновления в качестве второго аргумента: +Правильно будет использовать второй вариант вызова `setState()`, который принимает функцию, а не объект. Эта функция получит предыдущее состояние в качестве первого аргумента и значения пропсов непосредственно во время обновления в качестве второго аргумента: ```js // Правильно @@ -413,7 +415,9 @@ this.setState(function(state, props) { ## Однонаправленный поток данных {#the-data-flows-down} -В иерархии компонентов, ни родительский, ни дочерние компоненты не знают с состоянием (stateful) другие компоненты или без состояния (stateless). Также не важно, как был создан определенный компонент — с помощью функции или класса. Поэтому, состояние часто называют «локальным», «внутренним» или инкапсулированным. Оно доступно только для самого компонента и скрыто от других. +В иерархии компонентов, ни родительский, ни дочерние компоненты не знают задано ли состояние другого компонента. Также не важно, как был создан определенный компонент — с помощью функции или класса. + +Состояние часто называют «локальным», «внутренним» или инкапсулированным. Оно доступно только для самого компонента и скрыто от других. Компонент может передать своё состояние вниз по дереву в виде пропсов дочерних компонентов: From 55d8f195a7a06beb1e752466f18b4311b5c53db5 Mon Sep 17 00:00:00 2001 From: Andrew Goldis Date: Tue, 12 Feb 2019 05:45:06 +1100 Subject: [PATCH 09/10] Rewrite complex sentences, again --- content/docs/state-and-lifecycle.md | 34 ++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/content/docs/state-and-lifecycle.md b/content/docs/state-and-lifecycle.md index 2b7d95a0b..c0b5ca4fb 100644 --- a/content/docs/state-and-lifecycle.md +++ b/content/docs/state-and-lifecycle.md @@ -10,7 +10,7 @@ next: handling-events.html На этой странице представлены понятия «состояние» (state) и «жизненный цикл» (lifecycle) React-компонентов. Подробный [справочник API компонентов находится по этой ссылке](/docs/react-component.html). -В качестве примера рассмотрим идущие часы из [предыдущего раздела](/docs/rendering-elements.html#updating-the-rendered-element). В главе [Рендeринг элементов](/docs/rendering-elements.html#rendering-an-element-into-the-dom) мы изучили лишь один способ обновления UI — вызвать `ReactDOM.render()` для изменения результата рендера: +В качестве примера рассмотрим идущие часы из [предыдущего раздела](/docs/rendering-elements.html#updating-the-rendered-element). В главе [Рендeринг элементов](/docs/rendering-elements.html#rendering-an-element-into-the-dom) мы научились обновлять UI только одним способом — вызовом `ReactDOM.render()`: ```js{8-11} function tick() { @@ -31,7 +31,7 @@ setInterval(tick, 1000); [**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/gwoJZk?editors=0010) -В этой главе мы узнаем, как инкапсулировать и обеспечить многократное использование компонента `Clock`. Компонент самостоятельно создаст свой собственный таймер и будет самообновляться раз в секунду. +В этой главе мы узнаем, как инкапсулировать и обеспечить многократное использование компонента `Clock`. Компонент самостоятельно установит свой собственный таймер и будет обновляться раз в секунду. Для начала, извлечём компонент, показывающий время: @@ -70,7 +70,7 @@ ReactDOM.render( Для этого добавим так называемое «состояние» (state) в компонент `Clock`. -«Состояние» очень похоже на уже знакомые нам пропсы (props), отличие в том, что состояние контролируется и доступно только конкретному компоненту. +«Состояние» очень похоже на уже знакомые нам пропсы, отличие в том, что состояние контролируется и доступно только конкретному компоненту. Мы [уже упоминали](/docs/components-and-props.html#functional-and-class-components), что классовые компоненты обладают дополнительными способностями. Локальное «состояние» — одна из таких способностей, которое доступно только классовым компнентам. @@ -197,17 +197,17 @@ ReactDOM.render( [**Посмотреть на CodePen**](http://codepen.io/gaearon/pen/KgQpJd?editors=0010) -Теперь осталось только создать собственный таймер внутри `Clock` и обновлять компонент каждую секунду. +Теперь осталось только установить собственный таймер внутри `Clock` и обновлять компонент каждую секунду. ## Добавим методы жизненного цикла в класс {#adding-lifecycle-methods-to-a-class} В приложениях с множеством компонентов очень важно освобождать используемые системные ресурсы когда компоненты удаляются. -Первоначальный рендеринг компонента в DOM называется «монтирование» (установка). Нам нужно [создавать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) всякий раз, когда это происходит. +Первоначальный рендеринг компонента в DOM называется «монтирование» (установка). Нам нужно [устанавливать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) всякий раз, когда это происходит. -Каждый раз когда DOM-узел, созданный компонентом, удаляется, просходит то, что мы называем «размонтирование». Учитывая важность сохранения ресурсов, мы будем [сбрасывать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval) при каждой «размонтировке». +Каждый раз когда DOM-узел, созданный компонентом, удаляется, просходит то, что мы называем «размонтирование». Учитывая важность сохранения ресурсов, мы будем [сбрасывать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval) при каждом «размонтировании». -Объявим специальные методы, которые компонент будет вызывать при монтировнии и размонтировании: +Объявим специальные методы, которые компонент будет вызывать при монтировании и размонтировании: ```js{7-9,11-13} class Clock extends React.Component { @@ -237,7 +237,7 @@ class Clock extends React.Component { Эти методы называются «методами жизненного цикла» (lifecycle methods). -Метод `componentDidMount()` запускается после того, как компонент отрендерился в DOM — здесь мы и создадим таймер: +Метод `componentDidMount()` запускается после того, как компонент отрендерился в DOM — здесь мы и установим таймер: ```js{2-5} componentDidMount() { @@ -252,7 +252,7 @@ class Clock extends React.Component { В классовых компонентах у полей `this.props` и `this.state` особое назначение, более того, React сам создает `this.props`. Вы можете вручную добавить новые поля (например, ID таймера), если нужно сохранить дополнительную информацию о классе. -Удалим таймер в методе жизненного цикла `componentWillUnmount()`: +Теперь нам осталось сбросить таймер в методе жизненного цикла `componentWillUnmount()`: ```js{2} componentWillUnmount() { @@ -308,17 +308,17 @@ ReactDOM.render( Теперь часы обновляются каждую секунду. -Давайте рассмотрим наше решение и разберем порядок, в котором вызываются методы: +Давайте рассмотрим наше решение и разберём порядок, в котором вызываются методы: 1) Когда мы передаём `` в `ReactDOM.render()`, React вызывает конструктор компонента. `Clock` должен отображать текущее время, поэтому мы задаем начальное состояние `this.state` объектом с текущим временем. -2) React вызывает метод `render()` компонента `Clock`. Таким образом React узнаёт, что отобразить на экране. Далее, React обновляет DOM так, чтобы он соответствовал выводу ренедера `Clock`. +2) React вызывает метод `render()` компонента `Clock`. Таким образом React узнаёт, что отобразить на экране. Далее, React обновляет DOM так, чтобы он соответствовал выводу рендера `Clock`. -3) Как только вывод рендера `Clock` вставлен в DOM, React вызывает метод жизненного цикла `componentDidMount()`. Внутри него компонент `Clock` указывает браузеру создать таймер, который будет вызывать `tick()` раз в секунду. +3) Как только вывод рендера `Clock` вставлен в DOM, React вызывает метод жизненного цикла `componentDidMount()`. Внутри него компонент `Clock` указывает браузеру установить таймер, который будет вызывать `tick()` раз в секунду. -4) Таймер вызывает метод `tick()` ежесекундно. Часть метода — вызов `setState()` с объектом текущего времени — таким образом компонент `Clock` планирует обновление UI. Благодаря вызову `setState()` React знает, что состояние изменилось, и снова вызывает метод `render()`, чтобы узнать, что должно отображаться на экране. На этот раз `this.state.date` в методе `render()` будет другим, рендер компонента будет включать обновлённое время и React обновит DOM соответственно. +4) Таймер вызывает `tick()` ежесекундно. Внутри `tick()` мы меняем состояние посредством вызова `setState()` с текущим временем. React реагирует на изменение состояния и снова запускает `render()`. На этот раз `this.state.date` в методе `render()` содержит новое значение, поэтому React заменит DOM. Таким образом компонент `Clock` каждую секунду обновляет UI. -5) Если компонент `Clock` когда-либо удаляется из DOM, React вызывает метод жизненного цикла `componentWillUnmount()`, таким образом таймер будет остановлен и удален. +5) Если компонент `Clock` когда-либо удалится из DOM, React вызовет метод жизненного цикла `componentWillUnmount()` и сбросит таймер. ## Как правильно использовать состояние {#using-state-correctly} @@ -415,7 +415,7 @@ this.setState(function(state, props) { ## Однонаправленный поток данных {#the-data-flows-down} -В иерархии компонентов, ни родительский, ни дочерние компоненты не знают задано ли состояние другого компонента. Также не важно, как был создан определенный компонент — с помощью функции или класса. +В иерархии компонентов, ни родительский, ни дочерние компоненты не знают, задано ли состояние другого компонента. Также не важно, как был создан определенный компонент — с помощью функции или класса. Состояние часто называют «локальным», «внутренним» или инкапсулированным. Оно доступно только для самого компонента и скрыто от других. @@ -425,13 +425,13 @@ this.setState(function(state, props) {

Сейчас {this.state.date.toLocaleTimeString()}.

``` -Это также верно для пользовательских компонентов: +Своё состояние можно передать и другому пользовательскому компоненту: ```js ``` -Компонент `FormattedDate` получает `date` через пропсы но не знает, является ли первоисточником состояние `Clock`, пропс `Clock` или оно было передано напрямую: +Компонент `FormattedDate` получает `date` через пропсы но не знает, является ли первоисточником состояние `Clock`, пропсы `Clock` или оно было передано напрямую: ```js function FormattedDate(props) { From ee21a51693c267689d9da1fcdab69dc67deac425 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Tue, 12 Feb 2019 18:25:17 +0000 Subject: [PATCH 10/10] nits --- content/docs/state-and-lifecycle.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/content/docs/state-and-lifecycle.md b/content/docs/state-and-lifecycle.md index c0b5ca4fb..3368033a3 100644 --- a/content/docs/state-and-lifecycle.md +++ b/content/docs/state-and-lifecycle.md @@ -203,9 +203,9 @@ ReactDOM.render( В приложениях с множеством компонентов очень важно освобождать используемые системные ресурсы когда компоненты удаляются. -Первоначальный рендеринг компонента в DOM называется «монтирование» (установка). Нам нужно [устанавливать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) всякий раз, когда это происходит. +Первоначальный рендеринг компонента в DOM называется «монтирование» (mounting). Нам нужно [устанавливать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) всякий раз, когда это происходит. -Каждый раз когда DOM-узел, созданный компонентом, удаляется, просходит то, что мы называем «размонтирование». Учитывая важность сохранения ресурсов, мы будем [сбрасывать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval) при каждом «размонтировании». +Каждый раз когда DOM-узел, созданный компонентом, удаляется, просходит «размонтирование» (unmounting). Чтобы избежать утечки ресурсов, мы будем [сбрасывать таймер](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval) при каждом «размонтировании». Объявим специальные методы, которые компонент будет вызывать при монтировании и размонтировании: @@ -250,7 +250,7 @@ class Clock extends React.Component { Обратите внимание, что мы сохраняем ID таймера в `this`. -В классовых компонентах у полей `this.props` и `this.state` особое назначение, более того, React сам создает `this.props`. Вы можете вручную добавить новые поля (например, ID таймера), если нужно сохранить дополнительную информацию о классе. +Поля `this.props` и `this.state` в классах особенные, и их устанавливает сам React. Вы можете вручную добавить новые поля, если компоненту нужно хранить дополнительную информацию (например, ID таймера). Теперь нам осталось сбросить таймер в методе жизненного цикла `componentWillUnmount()`: @@ -260,7 +260,7 @@ class Clock extends React.Component { } ``` -Наконец, реализуем метод `tick()`. Он запускается таймером каждую секунду и использует `this.setState()`. +Наконец, реализуем метод `tick()`. Он запускается таймером каждую секунду и вызывает `this.setState()`. `this.setState()` планирует обновление внутреннего состояния компонента: @@ -316,7 +316,7 @@ ReactDOM.render( 3) Как только вывод рендера `Clock` вставлен в DOM, React вызывает метод жизненного цикла `componentDidMount()`. Внутри него компонент `Clock` указывает браузеру установить таймер, который будет вызывать `tick()` раз в секунду. -4) Таймер вызывает `tick()` ежесекундно. Внутри `tick()` мы меняем состояние посредством вызова `setState()` с текущим временем. React реагирует на изменение состояния и снова запускает `render()`. На этот раз `this.state.date` в методе `render()` содержит новое значение, поэтому React заменит DOM. Таким образом компонент `Clock` каждую секунду обновляет UI. +4) Таймер вызывает `tick()` ежесекундно. Внутри `tick()` мы просим React обновить состояние компонента, вызывая `setState()` с текущим временем. React реагирует на изменение состояния и снова запускает `render()`. На этот раз `this.state.date` в методе `render()` содержит новое значение, поэтому React заменит DOM. Таким образом компонент `Clock` каждую секунду обновляет UI. 5) Если компонент `Clock` когда-либо удалится из DOM, React вызовет метод жизненного цикла `componentWillUnmount()` и сбросит таймер. @@ -344,7 +344,7 @@ this.setState({comment: 'Hello'}); ### Обновления состояния могут быть асинхронными {#state-updates-may-be-asynchronous} -React может произвольно решить сгруппировать несколько вызовов `setState()` в одно обновление для улучшения производительности. +React может сгруппировать несколько вызовов `setState()` в одно обновление для улучшения производительности. Поскольку `this.props` и `this.state` могут обновляться асинхронно, вы не должны полагаться на их текущее значение для вычисления следующего состояния. @@ -431,7 +431,7 @@ this.setState(function(state, props) { ``` -Компонент `FormattedDate` получает `date` через пропсы но не знает, является ли первоисточником состояние `Clock`, пропсы `Clock` или оно было передано напрямую: +Компонент `FormattedDate` получает `date` через пропсы, но он не знает, откуда они взялись изначально — из состояния `Clock`, пропсов `Clock` или просто JavaScript-выражения: ```js function FormattedDate(props) { @@ -468,4 +468,4 @@ ReactDOM.render( У каждого компонента `Clock` есть собственное состояние таймера, которое обновляется независимо от других компонентов. -В React-приложениях, имеет ли компонент состояние или нет — это внутренняя деталь реализации компонента, которая может меняться со временем. Можно использовать компоненты без состояния в компонентах с состоянием, и наоборот. \ No newline at end of file +В React-приложениях, имеет ли компонент состояние или нет — это внутренняя деталь реализации компонента, которая может меняться со временем. Можно использовать компоненты без состояния в компонентах с состоянием, и наоборот.