diff --git a/content/docs/lifting-state-up.md b/content/docs/lifting-state-up.md index 449330cfd..5fc95f895 100644 --- a/content/docs/lifting-state-up.md +++ b/content/docs/lifting-state-up.md @@ -1,6 +1,6 @@ --- id: lifting-state-up -title: Lifting State Up +title: State-in Qaldırılması permalink: docs/lifting-state-up.html prev: forms.html next: composition-vs-inheritance.html @@ -9,24 +9,24 @@ redirect_from: - "docs/flux-todo-list.html" --- -Often, several components need to reflect the same changing data. We recommend lifting the shared state up to their closest common ancestor. Let's see how this works in action. +Bir çox zaman, bir neçə komponent eyni zamanda dəyişən məlumatdan istifadə etməli olurlar. Bu halda, paylaşılan state-i yaxın olan valideyn komponentə qaldırmağı tövsiyyə edirik. Gəlin bunun necə işlədiyinə baxaq. -In this section, we will create a temperature calculator that calculates whether the water would boil at a given temperature. +Bu bölmədə, verilən temperaturda suyun qaynayacağını hesablayan temperatur kalkulyatoru düzəldəcəyik. -We will start with a component called `BoilingVerdict`. It accepts the `celsius` temperature as a prop, and prints whether it is enough to boil the water: +`BoilingVerdict` adlanan komponent ilə başlayaq. Bu komponent, `celsius` temperaturunu prop kimi qəbul edib verilən temperaturda suyun qaynayacağını render edir: ```js{3,5} function BoilingVerdict(props) { if (props.celsius >= 100) { - return

The water would boil.

; + return

Su qaynayacaq.

; } - return

The water would not boil.

; + return

Su qaynamayacaq.

; } ``` -Next, we will create a component called `Calculator`. It renders an `` that lets you enter the temperature, and keeps its value in `this.state.temperature`. +İndi biz `Calculator` adında komponent düzəldəcəyik. Bu komponent, temperaturu daxil etmək üçün `` render edir və anket sahəsinin dəyərini `this.state.temperature` state-ində saxlayır. -Additionally, it renders the `BoilingVerdict` for the current input value. +Əlavə olaraq, cari temperatur dəyəri üçün `BoilingVerdict`-i render edir. ```js{5,9,13,17-21} class Calculator extends React.Component { @@ -44,7 +44,7 @@ class Calculator extends React.Component { const temperature = this.state.temperature; return (
- Enter temperature in Celsius: + Selsi ilə temperaturu daxil edin: @@ -56,18 +56,18 @@ class Calculator extends React.Component { } ``` -[**Try it on CodePen**](https://codepen.io/gaearon/pen/ZXeOBm?editors=0010) +[**CodePen-də sınayın**](https://codepen.io/gaearon/pen/ZXeOBm?editors=0010) -## Adding a Second Input {#adding-a-second-input} +## İkinci Anket Sahəsinin Əlavə Edilməsi {#adding-a-second-input} -Our new requirement is that, in addition to a Celsius input, we provide a Fahrenheit input, and they are kept in sync. +İndi yeni tələb, Selsidən əlavə Farenheit əlavə edib bu iki temperatur dəyərini sinxron saxlamaqdır. -We can start by extracting a `TemperatureInput` component from `Calculator`. We will add a new `scale` prop to it that can either be `"c"` or `"f"`: +Bunun üçün biz `TemperatureInput` komponentini `Calculator`-dan ayıra bilərik. Gəlin bu komponentə `"c"` və ya `"f"` qəbul edən `scale` propu əlavə edirik: ```js{1-4,19,22} const scaleNames = { - c: 'Celsius', - f: 'Fahrenheit' + c: 'Selsi', + f: 'Farenheit' }; class TemperatureInput extends React.Component { @@ -86,7 +86,7 @@ class TemperatureInput extends React.Component { const scale = this.props.scale; return (
- Enter temperature in {scaleNames[scale]}: + Temperaturu {scaleNames[scale]} ilə daxil et:
@@ -95,7 +95,7 @@ class TemperatureInput extends React.Component { } ``` -We can now change the `Calculator` to render two separate temperature inputs: +İndi `Calculator` iki fərqli temperatur sahəsi render edə bilər: ```js{5,6} class Calculator extends React.Component { @@ -110,15 +110,15 @@ class Calculator extends React.Component { } ``` -[**Try it on CodePen**](https://codepen.io/gaearon/pen/jGBryx?editors=0010) +[**CodePen-də sınayın**](https://codepen.io/gaearon/pen/jGBryx?editors=0010) -We have two inputs now, but when you enter the temperature in one of them, the other doesn't update. This contradicts our requirement: we want to keep them in sync. +İki sahənin olmasına baxmayaraq, temperaturu bir sahədə yenilədikdə o biri sahədə dəyər yenilənmir. Bu bizim bir tələbimizə ziddir: bu iki sahənin dəyəri sinxron saxlanmalıdır. -We also can't display the `BoilingVerdict` from `Calculator`. The `Calculator` doesn't know the current temperature because it is hidden inside the `TemperatureInput`. +Əlavə olaraq, `Calculator`-un `TemperatureInput`-da yerləşən cari temperaturdan xəbəri olmadığından `BoilingVerdict` komponentini `Calculator`-dan render etmək mümkün deyil. -## Writing Conversion Functions {#writing-conversion-functions} +## Çevrilmə Funksiyalarının Yazılması {#writing-conversion-functions} -First, we will write two functions to convert from Celsius to Fahrenheit and back: +İlk öncə, biz Selsini to Farenheitə və əskinə çevirmələr üçün funksiyalar yazacağıq: ```js function toCelsius(fahrenheit) { @@ -130,9 +130,9 @@ function toFahrenheit(celsius) { } ``` -These two functions convert numbers. We will write another function that takes a string `temperature` and a converter function as arguments and returns a string. We will use it to calculate the value of one input based on the other input. +Bu iki funksiya rəqəmləri çevirirlər. İndi biz `temperature` mətn arqumentini və çevirmə funksiyasını arqument kimi qəbul edən və mətn qaytaran funksiya yazacağıq. Biz bir anket sahəsinin dəyəri ilə digər anket sahəsinin dəyərini hesablamaq üçün bu funksiyadan istifadə edəcəyik. -It returns an empty string on an invalid `temperature`, and it keeps the output rounded to the third decimal place: +Etibarsız `temperature` dəyəri olduqda bu funksiya boş mətn qaytaracaq. Əks halda, nəticə 3-cü onluğa yuvarlaqlaşdırılacaq: ```js function tryConvert(temperature, convert) { @@ -146,11 +146,11 @@ function tryConvert(temperature, convert) { } ``` -For example, `tryConvert('abc', toCelsius)` returns an empty string, and `tryConvert('10.22', toFahrenheit)` returns `'50.396'`. +Məsələn, `tryConvert('abc', toCelsius)` boş mətn qaytarır. `tryConvert('10.22', toFahrenheit)` isə `'50.396'` qaytarır. -## Lifting State Up {#lifting-state-up} +## State-in Qaldırılması {#lifting-state-up} -Currently, both `TemperatureInput` components independently keep their values in the local state: +İndi, hər iki `TemperatureInput` komponenti dəyərlərləri müstəqil şəkildə lokal state-də saxlayırlar: ```js{5,9,13} class TemperatureInput extends React.Component { @@ -169,43 +169,43 @@ class TemperatureInput extends React.Component { // ... ``` -However, we want these two inputs to be in sync with each other. When we update the Celsius input, the Fahrenheit input should reflect the converted temperature, and vice versa. +Lakin, biz bu iki anket sahəsinin dəyərinin bir-birindən asılı olmasını istəyirik. Selsi sahəsi yeniləndikdə, Farenheit sahəsi çevrilmiş temperaturu göstərməli, Farenheit yeniləndikdə isə, Selsi sahəsi çevrilmiş temperaturu göstərməlidir. -In React, sharing state is accomplished by moving it up to the closest common ancestor of the components that need it. This is called "lifting state up". We will remove the local state from the `TemperatureInput` and move it into the `Calculator` instead. +Komponentlər arasında paylaşan state-i React-də yaratmaq üçün, state-i yaxın valideyn komponentə köçürmək lazımdır. Biz bunu "state-in qaldırılması" adlandırırıq. Gəlin `TemperatureInput`-dan lokal state-i silib `Calculator`-a köçürək. -If the `Calculator` owns the shared state, it becomes the "source of truth" for the current temperature in both inputs. It can instruct them both to have values that are consistent with each other. Since the props of both `TemperatureInput` components are coming from the same parent `Calculator` component, the two inputs will always be in sync. +Paylaşan state `Calculator`-da yerləşdirildikdə, bu komponent hər iki anket sahəsi üçün cari temperaturun həqiqət mənbəyi olur. Bu komponent, hər iki anket sahəsində bir-biri ilə uyğun olan dəyərin olmasını təlim edir. Hər iki `TemperatureInput`-un propları eyni valideyn `Calculator` komponentindən gəldiyindən, anket sahələri həmişə sinxronizasiyada olacaqlar. -Let's see how this works step by step. +Gəlin bunun işləməsinə addım addım baxaq. -First, we will replace `this.state.temperature` with `this.props.temperature` in the `TemperatureInput` component. For now, let's pretend `this.props.temperature` already exists, although we will need to pass it from the `Calculator` in the future: +İlk öncə, `TemperatureInput` komponentində `this.state.temperature`-ı `this.props.temperature`-a dəyişək. Gələcəkdə `Calculator`-dan `this.props.temperature` propunu göndərməyimizə baxmayaraq, hələki, iddia edək ki, bu prop mövcuddur: ```js{3} render() { - // Before: const temperature = this.state.temperature; + // Öncə: const temperature = this.state.temperature; const temperature = this.props.temperature; // ... ``` -We know that [props are read-only](/docs/components-and-props.html#props-are-read-only). When the `temperature` was in the local state, the `TemperatureInput` could just call `this.setState()` to change it. However, now that the `temperature` is coming from the parent as a prop, the `TemperatureInput` has no control over it. +Biz [propların yalnız oxuna bilən olduğunu](/docs/components-and-props.html#props-are-read-only) bilirik. `temperature` lokal state-də olduğu zaman, `TemperatureInput` komponenti `this.setState()` çağıraraq bu state-i dəyişə bilər. Lakin, `temperature`-un valideyn komponentdən prop kimi gəldiyindən `TemperatureInput` bu dəyəri idarə edə bilmir. -In React, this is usually solved by making a component "controlled". Just like the DOM `` accepts both a `value` and an `onChange` prop, so can the custom `TemperatureInput` accept both `temperature` and `onTemperatureChange` props from its parent `Calculator`. +React-də, komponenti "kontrol olunan" edərək bu problemi həll etmək mümkündür. DOM `` elementinin `value` və `onChange` propları qəbul etdiyi kimi, `TemperatureInput` xüsusi komponenti də `temperature` və `onTemperatureChange` proplarını valideyn komponenti olan `Calculator`-dan qəbul edə bilər. -Now, when the `TemperatureInput` wants to update its temperature, it calls `this.props.onTemperatureChange`: +`TemperatureInput` komponenti temperaturu yeniləmək istədikdə `this.props.onTemperatureChange` funksiyasını çağıra bilər: ```js{3} handleChange(e) { - // Before: this.setState({temperature: e.target.value}); + // Öncə: this.setState({temperature: e.target.value}); this.props.onTemperatureChange(e.target.value); // ... ``` ->Note: +>Qeyd: > ->There is no special meaning to either `temperature` or `onTemperatureChange` prop names in custom components. We could have called them anything else, like name them `value` and `onChange` which is a common convention. +>Xüsusi komponentlərdə `temperature` və ya `onTemperatureChange` prop adlarının olmasının heç bir xüsusiyyəti yoxdur. Biz bu propları nə istəsək adlandıra bilərik. Adətən, prop adlarını konvensiya kimi `value` və `onChange` adlandırırlar. -The `onTemperatureChange` prop will be provided together with the `temperature` prop by the parent `Calculator` component. It will handle the change by modifying its own local state, thus re-rendering both inputs with the new values. We will look at the new `Calculator` implementation very soon. +Valideyn `Calculator` komponenti `onTemperatureChange` propunu `temperature` propu ilə birlikdə təmin edir. Bu komponent lokal state-i yeniləyərək dəyəri dəyişib hər iki anket sahəsini yeni dəyərlər ilə render edə bilir. Biz `Calculator`-un yeni tətbiqinə birazdan baxacağıq. -Before diving into the changes in the `Calculator`, let's recap our changes to the `TemperatureInput` component. We have removed the local state from it, and instead of reading `this.state.temperature`, we now read `this.props.temperature`. Instead of calling `this.setState()` when we want to make a change, we now call `this.props.onTemperatureChange()`, which will be provided by the `Calculator`: +`Calculator`-da olan dəyişikliklərə keçmədən öncə, gəlin `TemperatureInput` komponentində etdiyimiz dəyişikliklərə baxaq. Bu komponentdən lokal state-i silib `this.state.temperature` oxumaq əvəzinə `this.props.temperature` propunu oxuyuruq. Dəyişiklik etmək üçün `this.setState()` çağırmaq əvəzinə `this.props.onTemperatureChange()` funksiyasını çağırırıq. Bu funksiya `Calculator` tərəfindən təmin edilir: ```js{8,12} class TemperatureInput extends React.Component { @@ -223,7 +223,7 @@ class TemperatureInput extends React.Component { const scale = this.props.scale; return (
- Enter temperature in {scaleNames[scale]}: + Temperaturu {scaleNames[scale]} ilə daxil edin:
@@ -232,11 +232,11 @@ class TemperatureInput extends React.Component { } ``` -Now let's turn to the `Calculator` component. +Gəlin indi `Calculator` komponentinə keçək. -We will store the current input's `temperature` and `scale` in its local state. This is the state we "lifted up" from the inputs, and it will serve as the "source of truth" for both of them. It is the minimal representation of all the data we need to know in order to render both inputs. +Cari anket sahəsinin `temperature` və `scale` dəyərlərini lokal state-də saxlayacağıq. Bu dəyərlər, anketlərdən "qaldırdığımız state-dir." Bu state hər iki sahə üçün "həqiqət mənbəyi" olub, hər iki sahəni render etmək üçün lazımdır. -For example, if we enter 37 into the Celsius input, the state of the `Calculator` component will be: +Məsələn, Selsi sahəsinə 37 daxil etdikdə, `Calculator` komponentinin state-i aşağıdaki formada olacaq: ```js { @@ -245,7 +245,7 @@ For example, if we enter 37 into the Celsius input, the state of the `Calculator } ``` -If we later edit the Fahrenheit field to be 212, the state of the `Calculator` will be: +Əgər Fahrenheit sahəsini 212-ə dəyişdikdə, `Calculator`-un state-i aşağıdaki formada olacaq: ```js { @@ -254,9 +254,9 @@ If we later edit the Fahrenheit field to be 212, the state of the `Calculator` w } ``` -We could have stored the value of both inputs but it turns out to be unnecessary. It is enough to store the value of the most recently changed input, and the scale that it represents. We can then infer the value of the other input based on the current `temperature` and `scale` alone. +Biz hər iki dəyəri saxlaya bilərdik amma bu lazımsızdır. Yeni dəyişmiş sahənin dəyərini və təmsil etdiyi bölgünü saxlamaq kifayətdir. Saxlanılan dəyər əsasında digər sahənin `temperature` and `scale` dəyərlərini hesablamaq mümkündür. -The inputs stay in sync because their values are computed from the same state: +Dəyərlər eyni state əsasında hesablandığından sahələri sinxron saxlamaq mümkündür: ```js{6,10,14,18-21,27-28,31-32,34} class Calculator extends React.Component { @@ -299,32 +299,32 @@ class Calculator extends React.Component { } ``` -[**Try it on CodePen**](https://codepen.io/gaearon/pen/WZpxpz?editors=0010) +[**CodePen-də sınayın**](https://codepen.io/gaearon/pen/WZpxpz?editors=0010) -Now, no matter which input you edit, `this.state.temperature` and `this.state.scale` in the `Calculator` get updated. One of the inputs gets the value as is, so any user input is preserved, and the other input value is always recalculated based on it. +İndi hansı sahənin dəyişildiyindən asılı olmayaraq, `Calculator`-un `this.state.temperature` və `this.state.scale` state-ləri yenilənəcək. Bir sahə, dəyəri olduğu kimi qəbul edir. Digər sahə isə bu sahənin dəyəri əsasında yenidən hesablanır. -Let's recap what happens when you edit an input: +Sahədə dəyişikliklər edildikdə nə baş verdiyinə yenidən baxaq: -* React calls the function specified as `onChange` on the DOM ``. In our case, this is the `handleChange` method in the `TemperatureInput` component. -* The `handleChange` method in the `TemperatureInput` component calls `this.props.onTemperatureChange()` with the new desired value. Its props, including `onTemperatureChange`, were provided by its parent component, the `Calculator`. -* When it previously rendered, the `Calculator` has specified that `onTemperatureChange` of the Celsius `TemperatureInput` is the `Calculator`'s `handleCelsiusChange` method, and `onTemperatureChange` of the Fahrenheit `TemperatureInput` is the `Calculator`'s `handleFahrenheitChange` method. So either of these two `Calculator` methods gets called depending on which input we edited. -* Inside these methods, the `Calculator` component asks React to re-render itself by calling `this.setState()` with the new input value and the current scale of the input we just edited. -* React calls the `Calculator` component's `render` method to learn what the UI should look like. The values of both inputs are recomputed based on the current temperature and the active scale. The temperature conversion is performed here. -* React calls the `render` methods of the individual `TemperatureInput` components with their new props specified by the `Calculator`. It learns what their UI should look like. -* React calls the `render` method of the `BoilingVerdict` component, passing the temperature in Celsius as its props. -* React DOM updates the DOM with the boiling verdict and to match the desired input values. The input we just edited receives its current value, and the other input is updated to the temperature after conversion. +* DOM ``-unda göstərilən `onChange` funksiyası React tərəfindən çağrılır. Bizim halda, bu funksiya `TemperatureInput` komponentində olan `handleChange` funksiyasıdır. +* `TemperatureInput` komponentində olan `handleChange` funksiyası `this.props.onTemperatureChange()` funksiyasını lazımi dəyər ilə çağırır. `onTemperatureChange` daxil olmaqla, bu komponentin propları valideyn komponenti olan `Calculator` tərəfindən təmin edilir. +* Əvvəlki renderdə, Selsi `TemperatureInput` komponentinin `onTemperatureChange` propuna `Calculator` komponentinin `handleCelsiusChange` funksiyası göndərilir. Farenheit `TemperatureInput` komponentinin `onTemperatureChange` propuna isə `Calculator` komponentinin `handleFahrenheitChange` funksiyası göndərilir. Yenilənən anket sahəsinə uyğun göstərilən funksiya çağrılır. +* `Calculator` komponenti bu funksiyanda, dəyişən anket sahəsinin dəyəri və bölgüsü ilə `this.setState()` funksiyasını çağdığından, React bu komponenti yenidən render edir. +* React, `Calculator` komponentinin `render` funksiyasını çağıraraq UI-ın necə görünəcəyini göstərir. Hər iki anket sahəsinin dəyəri cari temperatur və bölgü əsasında hesablanır. Temperatur çevrilməsi burada baş verir. +* React, fərdi `TemperatureInput` komponentlərinin `render` funksiyalarını `Calculator` tərəfindən göstərilən proplar əsasında çağırır. UI-ın necə olacağı göstərilir. +* React, Selsi temperaturunu prop kimi göndərərək `BoilingVerdict` komponentinin `render` funksiyasını çağırır. +* React DOM, qaynama iddiası və anket sahələrinin dəyərləri əsasında DOM-u yeniləyir. Bizim dəyişdiyimiz anket sahəsi cari dəyəri qəbul edir. Digər anket sahəsi isə çevrilmədən sonra hesablanan temperaturu göstərir. -Every update goes through the same steps so the inputs stay in sync. +Hər yenilik eyni addımlardan keçərək anket sahələrini sinxron saxlayır. -## Lessons Learned {#lessons-learned} +## Nə Öyrəndik {#lessons-learned} -There should be a single "source of truth" for any data that changes in a React application. Usually, the state is first added to the component that needs it for rendering. Then, if other components also need it, you can lift it up to their closest common ancestor. Instead of trying to sync the state between different components, you should rely on the [top-down data flow](/docs/state-and-lifecycle.html#the-data-flows-down). +React applikasiyalarında dəyişən məlumat üçün həmiçə tək "həqiqət mənbəyi" olmalıdır. Adətən, ilk olaraq render olunmuş komponentə state əlavə edirik. Digər komponentlərə bu dəyər lazım olduqda, state-i valideyn komponentlərə qaldırırıq. Fəqrli komponentlər arası state-i sinxron etmək əvəzinə [yuxarıdan aşağı məlumat axınından](/docs/state-and-lifecycle.html#the-data-flows-down) istifadə edin. -Lifting state involves writing more "boilerplate" code than two-way binding approaches, but as a benefit, it takes less work to find and isolate bugs. Since any state "lives" in some component and that component alone can change it, the surface area for bugs is greatly reduced. Additionally, you can implement any custom logic to reject or transform user input. +İki-yollu binding yanaşmasından fərqli olaraq state-i qaldırmaq yanaşması daha çox kodun yazılmasına səbəb olur. Amma bu yanaşma ilə baqları tapıb düzəltmək daha asandır. State həmişə hər hansı bir komponentdə "yaşadığından" və bu komponent state-i dəyişə bildiyindən, baqların əhatə sahəsi çox kiçilir. Əlavə olaraq, istifadəçi daxil olmasını rədd etmək və ya çevirmək üçün xüsusi məntiq tətbiq etmən mümkün olur. -If something can be derived from either props or state, it probably shouldn't be in the state. For example, instead of storing both `celsiusValue` and `fahrenheitValue`, we store just the last edited `temperature` and its `scale`. The value of the other input can always be calculated from them in the `render()` method. This lets us clear or apply rounding to the other field without losing any precision in the user input. +Əgər nəsə həm proplardan həm də state-dən törənə bilərsə, bu state-də olmamalıdır. Məsələn, `celsiusValue` və `fahrenheitValue` dəyərlərini state-də saxlamaq əvəzinə, biz son dəyişən sahənin dəyərini və bölgüsünü `temperature` və `scale`-də saxlaya bilirik. Digər sahənin dəyəri `render()` funksiyasında, cari dəyərin əsasında hesablana bilər. Bu yanaşma, dəqiqliyi itirmədən digər sahənin dəyərini yuvarlaqlaşdırmağa imkan yaradır. -When you see something wrong in the UI, you can use [React Developer Tools](https://github.com/facebook/react-devtools) to inspect the props and move up the tree until you find the component responsible for updating the state. This lets you trace the bugs to their source: +UI-da səhv gördüyünüz zaman, propları yoxlayıb ağacdan yuxarı qalxaraq state-i yeniləyən komponenti tapmaq üçün [React Proqramçı Alətlərindən](https://github.com/facebook/react-devtools) istifadə edə bilərsiniz. Bu alətlər, baqların mənbəyini tapmağa imkan yaradır: -Monitoring State in React DevTools +React Proqramçı Alətlərində State-in Yoxlanması