[Rus] Improved the translation of Redux challenges (part 3) (#34353)

* Improved the translation

* Improved the translation

* Improved the translation

* Improved the translation

* Improved the translation
This commit is contained in:
elcodex
2019-05-14 08:54:02 +03:00
committed by Randell Dawson
parent 791e589c93
commit 171b762775
5 changed files with 49 additions and 50 deletions

View File

@ -8,21 +8,21 @@ localeTitle: Объединение нескольких редукторов
---
## Description
<section id="description"> Когда состояние вашего приложения начинает становиться более сложным, может возникнуть соблазн разделить состояние на несколько частей. Вместо этого запомните первый принцип Redux: все состояние приложения хранится в одном объекте состояния в хранилище. Поэтому Redux обеспечивает композицию редуктора как решение для сложной модели состояния. Вы определяете несколько редукторов для обработки разных частей состояния вашего приложения, а затем объединяете эти редукторы в один редуктор корня. Корневой редуктор затем передается в метод Redux <code>createStore()</code> . Чтобы объединить несколько редукторов вместе, Redux предоставляет метод <code>combineReducers()</code> . Этот метод принимает объект как аргумент, в котором вы определяете свойства, которые связывают ключи с конкретными функциями редуктора. Имя, которое вы передаете клавишам, будет использоваться Redux как имя связанного участка состояния. Как правило, хорошей практикой является создание редуктора для каждой части состояния приложения, когда они являются определенными или уникальными в некотором роде. Например, в приложении для заметок с аутентификацией пользователя один редуктор может обрабатывать аутентификацию, а другой - текст и заметки, которые пользователь отправляет. Для такого приложения мы можем написать метод <code>combineReducers()</code> следующим образом: <blockquote> const rootReducer = Redux.combineReducers ({ <br> auth: authenticationReducer, <br> примечания: примечанияReducer <br> }); </blockquote> Теперь ключевые <code>notes</code> будут содержать все состояние, связанное с нашими заметками и обрабатываемое нашими <code>notesReducer</code> . Так можно создать несколько редукторов для управления более сложным состоянием приложения. В этом примере состояние, хранящееся в хранилище Redux, будет тогда единственным объектом, содержащим свойства <code>auth</code> и <code>notes</code> . </section>
<section id="description"> Когда состояние вашего приложения начинает становиться более сложным, может возникнуть соблазн разделить состояние на несколько частей. Вместо этого запомните первый принцип Redux: все состояние приложения хранится в одном объекте состояния в хранилище. Поэтому Redux предоставляет композицию редукторов как решение для сложной модели состояния. Вы определяете несколько редукторов для обработки разных частей состояния вашего приложения, а затем объединяете эти редукторы в один корневой редуктор. Корневой редуктор затем передается в метод Redux <code>createStore()</code> . Чтобы объединить несколько редукторов вместе, в Redux есть метод <code>combineReducers()</code> . Этот метод принимает объект как аргумент, в котором вы определяете свойства, которые связывают ключи с конкретными функциями редуктора. Имя, которое вы задаёте ключам, будет использоваться Redux как имя для связанной части состояния. Как правило, хорошей практикой является создание редуктора для каждой части состояния приложения, когда они являются особенными или уникальными в некотором роде. Например, в приложении для заметок с аутентификацией пользователя один редуктор может обрабатывать аутентификацию, а другой - текст и заметки, которые пользователь отправляет. Для такого приложения мы можем написать метод <code>combineReducers()</code> следующим образом: <blockquote> const rootReducer = Redux.combineReducers ({ <br> auth: authenticationReducer, <br> notes: notesReducer <br> }); </blockquote> Теперь ключ <code>notes</code> будет содержать все состояние, связанное с нашими заметками и обрабатываемое нашим <code>notesReducer</code> . Так можно создать несколько редукторов для управления более сложным состоянием приложения. В этом примере состояние, находящееся в хранилище Redux, будет тогда единственным объектом, содержащим свойства <code>auth</code> и <code>notes</code> . </section>
## Instructions
<section id="instructions"> В <code>counterReducer()</code> имеются функции <code>counterReducer()</code> и <code>authReducer()</code> , а также хранилище Redux. Завершите запись функции <code>rootReducer()</code> с помощью <code>Redux.combineReducers()</code> . Назначьте <code>counterReducer</code> ключу с именем <code>count</code> и <code>authReducer</code> на ключ с именем <code>auth</code> . </section>
<section id="instructions"> В редакторе кода заданы функции <code>counterReducer()</code> и <code>authReducer()</code> , а также хранилище Redux. Завершите написание функции <code>rootReducer()</code> , используя <code>Redux.combineReducers()</code> . Назначьте <code>counterReducer</code> ключу с именем <code>count</code> и <code>authReducer</code> - ключу с именем <code>auth</code> . </section>
## Tests
<section id='tests'>
```yml
tests:
- text: <code>counterReducer</code> должен увеличивать и <code>counterReducer</code> <code>state</code> .
- text: <code>counterReducer</code> должен увеличивать и уменьшать <code>state</code> .
testString: 'assert((function() { const initalState = store.getState().count; store.dispatch({type: INCREMENT}); store.dispatch({type: INCREMENT}); const firstState = store.getState().count; store.dispatch({type: DECREMENT}); const secondState = store.getState().count; return firstState === initalState + 2 && secondState === firstState - 1 })(), "The <code>counterReducer</code> should increment and decrement the <code>state</code>.");'
- text: <code>authReducer</code> должен переключать <code>state</code> <code>authenticated</code> между <code>true</code> и <code>false</code> .
testString: 'assert((function() { store.dispatch({type: LOGIN}); const loggedIn = store.getState().auth.authenticated; store.dispatch({type: LOGOUT}); const loggedOut = store.getState().auth.authenticated; return loggedIn === true && loggedOut === false })(), "The <code>authReducer</code> should toggle the <code>state</code> of <code>authenticated</code> between <code>true</code> and <code>false</code>.");'
- text: 'Магазин <code>state</code> должно иметь два ключа: <code>count</code> , который содержит номер и <code>auth</code> , который содержит объект. Объект <code>auth</code> должен иметь свойство <code>authenticated</code> , которое содержит логическое значение.'
- text: 'Хранилище <code>state</code> должно иметь два ключа: <code>count</code> , который содержит число и <code>auth</code> , который содержит объект. Объект <code>auth</code> должен иметь свойство <code>authenticated</code> , которое содержит логическое значение.'
testString: 'assert((function() { const state = store.getState(); return typeof state.auth === "object" && typeof state.auth.authenticated === "boolean" && typeof state.count === "number" })(), "The store <code>state</code> should have two keys: <code>count</code>, which holds a number, and <code>auth</code>, which holds an object. The <code>auth</code> object should have a property of <code>authenticated</code>, which holds a boolean.");'
- text: '<code>rootReducer</code> должен быть функцией, которая объединяет <code>counterReducer</code> и <code>authReducer</code> .'
testString: 'getUserInput => assert((function() { const noWhiteSpace = getUserInput("index").replace(/\s/g,""); return typeof rootReducer === "function" && noWhiteSpace.includes("Redux.combineReducers") })(), "The <code>rootReducer</code> should be a function that combines the <code>counterReducer</code> and the <code>authReducer</code>.");'
@ -69,7 +69,7 @@ const authReducer = (state = {authenticated: false}, action) => {
}
};
const rootReducer = // define the root reducer here
const rootReducer = // определите здесь корневой редуктор
const store = Redux.createStore(rootReducer);

View File

@ -4,14 +4,14 @@ title: Register a Store Listener
challengeType: 6
isRequired: false
videoUrl: ''
localeTitle: Зарегистрировать слушателя магазина
localeTitle: Регистрация слушателя хранилища
---
## Description
<section id="description"> Другой метод, к <code>store.subscribe()</code> вас есть доступ к объекту <code>store</code> Redux, - <code>store.subscribe()</code> . Это позволяет вам подписывать функции слушателя в хранилище, которые вызывается всякий раз, когда действие отправляется против магазина. Одним из простых способов использования этого метода является подписка функции на ваш магазин, которая просто регистрирует сообщение каждый раз, когда принимается действие, и хранилище обновляется. </section>
<section id="description"> Другой метод, к которому у вас есть доступ из Redux <code>store</code>, - это <code>store.subscribe()</code> . Он позволяет вам подписать функции слушателя к хранилищу, которые будут вызываться всякий раз, когда действие отправляется в хранилище. Одним из простых способов использования этого метода является подписка функции на ваше хранилище, которая просто регистрирует сообщение каждый раз, когда принимается действие, и хранилище обновляется. </section>
## Instructions
<section id="instructions"> Написать функцию обратного вызова , который увеличивает глобальную переменную <code>count</code> каждый раз , когда магазин принимает действие, и передать эту функцию в к <code>store.subscribe()</code> метода. Вы увидите, что <code>store.dispatch()</code> вызывается три раза подряд, каждый раз непосредственно передавая объект действия. Посмотрите вывод консоли между диспетчерами действий, чтобы увидеть обновления. </section>
<section id="instructions"> Написать функцию обратного вызова, которая увеличивает значение глобальной переменной <code>count</code> каждый раз, когда хранилище принимает действие, и передать эту функцию в метод <code>store.subscribe()</code> . Вы увидите, что <code>store.dispatch()</code> вызывается три раза подряд, каждый раз непосредственно передавая объект действия. Посмотрите вывод консоли между отправками действия, чтобы увидеть, что обновления происходят. </section>
## Tests
<section id='tests'>
@ -20,11 +20,10 @@ localeTitle: Зарегистрировать слушателя магазин
tests:
- text: Отправка действия <code>ADD</code> в хранилище должна увеличивать состояние на <code>1</code> .
testString: 'assert((function() { const initialState = store.getState(); store.dispatch({ type: "ADD" }); const newState = store.getState(); return newState === (initialState + 1); })(), "Dispatching the <code>ADD</code> action on the store should increment the state by <code>1</code>.");'
- text: 'Должна быть функция прослушивателя, подписанная на магазин, используя <code>store.subscribe</code> .'
- text: 'Должна быть функция слушателя, подписанная на хранилище, используя <code>store.subscribe</code> .'
testString: 'getUserInput => assert(getUserInput("index").includes("store.subscribe("), "There should be a listener function subscribed to the store using <code>store.subscribe</code>.");'
- text: Обратный вызов <code>store.subscribe</code> также должен увеличивать глобальную переменную <code>count</code> при обновлении хранилища.
- text: Обратный вызов в <code>store.subscribe</code> также должен увеличивать значение глобальной переменной <code>count</code> при обновлении хранилища.
testString: 'assert(store.getState() === count, "The callback to <code>store.subscribe</code> should also increment the global <code>count</code> variable as the store is updated.");'
```
</section>
@ -48,12 +47,12 @@ const reducer = (state = 0, action) => {
const store = Redux.createStore(reducer);
// global count variable:
// глобальная переменная счётчика:
let count = 0;
// change code below this line
// измените код ниже этой линии
// change code above this line
// измените код выше этой линии
store.dispatch({type: ADD});
console.log(count);

View File

@ -4,31 +4,31 @@ title: Use a Switch Statement to Handle Multiple Actions
challengeType: 6
isRequired: false
videoUrl: ''
localeTitle: Используйте инструкцию Switch для обработки нескольких действий
localeTitle: Использование инструкции Switch для обработки нескольких действий
---
## Description
<section id="description"> Вы можете сказать магазину Redux, как обрабатывать несколько типов действий. Скажите, что вы управляете аутентификацией пользователя в своем хранилище Redux. Вы хотите иметь представление состояния, когда пользователи вошли в систему и когда они вышли из системы. Вы представляете это с единственным объектом состояния с <code>authenticated</code> свойством. Вам также нужны создатели действий, которые создают действия, соответствующие логину пользователя и пользователю, а также сами объекты действий. </section>
<section id="description"> Вы можете сказать хранилищу Redux, как обрабатывать несколько типов действий. Предположим, что вы управляете аутентификацией пользователя в своем хранилище Redux. Вы хотите,чтобы у вас было состояние, показывающее когда пользователи вошли в систему и когда они вышли из системы. Вы представляете это единственным объектом состояния со свойством <code>authenticated</code>. Вам также нужны создатели действий, которые создают действия, отвечающие за вход пользователя и за выход пользователя из системы, а также сами объекты действий. </section>
## Instructions
<section id="instructions"> В редакторе кода есть создатели хранилища, действия и действия. Заполните функцию <code>reducer</code> для обработки нескольких действий аутентификации. Используйте оператор <code>switch</code> JavaScript в <code>reducer</code> чтобы реагировать на различные события действий. Это стандартный образец при записи редукторов Redux. Оператор switch должен переключать <code>action.type</code> и возвращать соответствующее состояние аутентификации. <strong>Примечание.</strong> На этом этапе не беспокойтесь о неизменности состояния, поскольку в этом примере оно мало и просто. Для каждого действия вы можете вернуть новый объект - например <code>{authenticated: true}</code> . Кроме того, не забудьте написать случай по <code>default</code> в вашем операторе switch, который возвращает текущее <code>state</code> . Это важно, потому что, как только ваше приложение имеет несколько редукторов, все они запускаются в любое время, когда происходит отправка действий, даже если действие не связано с этим редуктором. В таком случае вы хотите убедиться, что вы вернете текущее <code>state</code> . </section>
<section id="instructions"> В редакторе кода для вас уже описаны хранилище, действия и создатели действия. Заполните функцию <code>reducer</code> для обработки различных действий аутентификации. Используйте JavaScript оператор <code>switch</code> в <code>reducer</code> чтобы реагировать на различные события действий. Это стандартный паттерн при описание редукторов Redux. Оператор switch должен переключаться между <code>action.type</code> и возвращать соответствующее состояние аутентификации. <strong>Примечание.</strong> На этом этапе не беспокойтесь о неизменности состояния, поскольку это маленький и простой пример. Для каждого действия вы можете вернуть новый объект - например, <code>{authenticated: true}</code> . Кроме того, не забудьте написать случай по умолчанию <code>default</code> в вашем операторе switch, который возвращает текущее <code>state</code> . Это важно, потому что когда в вашем приложении несколько редукторов, все они запускаются, когда происходит отправка действий, даже если действие не связано с этим редуктором. В таком случае вы хотите убедиться, что вы вернете текущее <code>state</code> . </section>
## Tests
<section id='tests'>
```yml
tests:
- text: 'Вызов функции <code>loginUser</code> должен вернуть объект с свойством type, установленным в строку <code>LOGIN</code> .'
- text: 'Вызов функции <code>loginUser</code> должен вернуть объект со свойством type, установленным в строковое значение <code>LOGIN</code> .'
testString: 'assert(loginUser().type === "LOGIN", "Calling the function <code>loginUser</code> should return an object with type property set to the string <code>LOGIN</code>.");'
- text: 'Вызов функции <code>logoutUser</code> должен вернуть объект с свойством типа, установленным в строку <code>LOGOUT</code> .'
- text: 'Вызов функции <code>logoutUser</code> должен вернуть объект со свойством type, установленным в строковое значение <code>LOGOUT</code> .'
testString: 'assert(logoutUser().type === "LOGOUT", "Calling the function <code>logoutUser</code> should return an object with type property set to the string <code>LOGOUT</code>.");'
- text: 'Магазин должен быть инициализирован объектом с <code>authenticated</code> свойством, установленным на <code>false</code> .'
- text: 'Хранилище должно быть инициализировано объектом со свойством <code>authenticated</code> , установленным в <code>false</code> .'
testString: 'assert(store.getState().authenticated === false, "The store should be initialized with an object with an <code>authenticated</code> property set to <code>false</code>.");'
- text: Dispatching <code>loginUser</code> должен обновить <code>authenticated</code> свойство в состоянии хранилища до <code>true</code> .
- text: Отправка <code>loginUser</code> должна обновить <code>authenticated</code> свойство в состоянии хранилища на <code>true</code> .
testString: 'assert((function() { const initialState = store.getState(); store.dispatch(loginUser()); const afterLogin = store.getState(); return initialState.authenticated === false && afterLogin.authenticated === true })(), "Dispatching <code>loginUser</code> should update the <code>authenticated</code> property in the store state to <code>true</code>.");'
- text: Dispatching <code>logoutUser</code> должен обновить <code>authenticated</code> свойство в состоянии хранилища до <code>false</code> .
- text: Отправка <code>logoutUser</code> должна обновить <code>authenticated</code> свойство в состоянии хранилища на <code>false</code> .
testString: 'assert((function() { store.dispatch(loginUser()); const loggedIn = store.getState(); store.dispatch(logoutUser()); const afterLogout = store.getState(); return loggedIn.authenticated === true && afterLogout.authenticated === false })(), "Dispatching <code>logoutUser</code> should update the <code>authenticated</code> property in the store state to <code>false</code>.");'
- text: Функция <code>authReducer</code> должна обрабатывать несколько типов действий с помощью оператора <code>switch</code> .
- text: Функция <code>authReducer</code> должна обрабатывать разные типы действий с помощью оператора <code>switch</code> .
testString: 'getUserInput => assert( getUserInput("index").toString().includes("switch") && getUserInput("index").toString().includes("case") && getUserInput("index").toString().includes("default"), "The <code>authReducer</code> function should handle multiple action types with a <code>switch</code> statement.");'
```
@ -46,9 +46,9 @@ const defaultState = {
};
const authReducer = (state = defaultState, action) => {
// change code below this line
// измените код ниже этой линии
// change code above this line
// измените код выше этой линии
};
const store = Redux.createStore(authReducer);

View File

@ -4,35 +4,35 @@ title: Use const for Action Types
challengeType: 6
isRequired: false
videoUrl: ''
localeTitle: Использовать const для типов действий
localeTitle: Использование констант для типов действий
---
## Description
<section id="description"> Общей практикой при работе с Redux является назначение типов действий как констант только для чтения, а затем ссылки на эти константы везде, где они используются. Вы можете реорганизовать код, с которым работаете, чтобы написать типы действий как объявления <code>const</code> . </section>
<section id="description"> Общей практикой при работе с Redux является присваивать типы действий константам, а затем ссылаться на эти константы везде, где они используются. Вы можете реорганизовать код, с которым работаете, чтобы описать типы действий константами <code>const</code> . </section>
## Instructions
<section id="instructions"> Объявите <code>LOGIN</code> и <code>LOGOUT</code> как <code>const</code> значения и назначьте их в <code>&#39;LOGIN&#39;</code> и <code>&#39;LOGOUT&#39;</code> строк соответственно. Затем отредактируйте <code>authReducer()</code> и создателей действия, чтобы ссылаться на эти константы вместо строковых значений. <strong>Примечание.</strong> Обычно принято писать константы во всех прописных буквах, и это стандартная практика в Redux. </section>
<section id="instructions"> Объявите <code>LOGIN</code> и <code>LOGOUT</code> как константы <code>const</code> и присвойте им строковые значения <code>&#39;LOGIN&#39;</code> и <code>&#39;LOGOUT&#39;</code> соответственно. Затем отредактируйте <code>authReducer()</code> и создателей действия, чтобы они ссылались на эти константы вместо строковых значений. <strong>Примечание.</strong> Обычно принято писать константы прописными буквами, и это стандартная практика в Redux. </section>
## Tests
<section id='tests'>
```yml
tests:
- text: Вызов функции <code>loginUser</code> должен вернуть объект с свойством <code>type</code> установленным в строку <code>LOGIN</code> .
- text: Вызов функции <code>loginUser</code> должен вернуть объект со свойством <code>type</code> , установленным в строку <code>LOGIN</code> .
testString: 'assert(loginUser().type === "LOGIN", "Calling the function <code>loginUser</code> should return an object with <code>type</code> property set to the string <code>LOGIN</code>.");'
- text: Вызов функции <code>logoutUser</code> должен вернуть объект с свойством <code>type</code> установленным в строку <code>LOGOUT</code> .
- text: Вызов функции <code>logoutUser</code> должен вернуть объект со свойством <code>type</code> , установленным в строку <code>LOGOUT</code> .
testString: 'assert(logoutUser().type === "LOGOUT", "Calling the function <code>logoutUser</code> should return an object with <code>type</code> property set to the string <code>LOGOUT</code>.");'
- text: Магазин должен быть инициализирован объектом с идентификатором <code>login</code> установленным в значение <code>false</code> .
- text: Хранилище должно быть инициализировано объектом с идентификатором <code>login</code> , установленным в значение <code>false</code> .
testString: 'assert(store.getState().authenticated === false, "The store should be initialized with an object with property <code>login</code> set to <code>false</code>.");'
- text: Dispatching <code>loginUser</code> должен обновить свойство <code>login</code> в состоянии store до <code>true</code> .
- text: Отправка <code>loginUser</code> должна обновить свойство <code>login</code> в состоянии хранилища до <code>true</code> .
testString: 'assert((function() { const initialState = store.getState(); store.dispatch(loginUser()); const afterLogin = store.getState(); return initialState.authenticated === false && afterLogin.authenticated === true })(), "Dispatching <code>loginUser</code> should update the <code>login</code> property in the store state to <code>true</code>.");'
- text: Dispatching <code>logoutUser</code> должен обновить свойство <code>login</code> в состоянии store до <code>false</code> .
- text: Отправка <code>logoutUser</code> должна обновить свойство <code>login</code> в состоянии хранилища до <code>false</code> .
testString: 'assert((function() { store.dispatch(loginUser()); const loggedIn = store.getState(); store.dispatch(logoutUser()); const afterLogout = store.getState(); return loggedIn.authenticated === true && afterLogout.authenticated === false })(), "Dispatching <code>logoutUser</code> should update the <code>login</code> property in the store state to <code>false</code>.");'
- text: Функция <code>authReducer</code> должна обрабатывать несколько типов действий с помощью оператора switch.
- text: Функция <code>authReducer</code> должна обрабатывать разные типы действий с помощью оператора switch.
testString: 'getUserInput => assert((function() { return typeof authReducer === "function" && getUserInput("index").toString().includes("switch") && getUserInput("index").toString().includes("case") && getUserInput("index").toString().includes("default") })(), "The <code>authReducer</code> function should handle multiple action types with a switch statement.");'
- text: <code>LOGIN</code> и <code>LOGOUT</code> должны быть объявлены как значения <code>const</code> и должны быть назначены строки <code>LOGIN</code> и <code>LOGOUT</code> .
- text: <code>LOGIN</code> и <code>LOGOUT</code> должны быть объявлены как значения <code>const</code> и должны быть проинициализированы строками <code>LOGIN</code> и <code>LOGOUT</code> .
testString: 'getUserInput => assert((function() { const noWhiteSpace = getUserInput("index").toString().replace(/\s/g,""); return (noWhiteSpace.includes("constLOGIN=\"LOGIN\"") || noWhiteSpace.includes("constLOGIN="LOGIN"")) && (noWhiteSpace.includes("constLOGOUT=\"LOGOUT\"") || noWhiteSpace.includes("constLOGOUT="LOGOUT"")) })(), "<code>LOGIN</code> and <code>LOGOUT</code> should be declared as <code>const</code> values and should be assigned strings of <code>LOGIN</code>and <code>LOGOUT</code>.");'
- text: Создатели действия и редуктор должны ссылаться на константы <code>LOGIN</code> и <code>LOGOUT</code> .
- text: Создатели действий и редуктор должны ссылаться на константы <code>LOGIN</code> и <code>LOGOUT</code> .
testString: 'getUserInput => assert((function() { const noWhiteSpace = getUserInput("index").toString().replace(/\s/g,""); return noWhiteSpace.includes("caseLOGIN:") && noWhiteSpace.includes("caseLOGOUT:") && noWhiteSpace.includes("type:LOGIN") && noWhiteSpace.includes("type:LOGOUT") })(), "The action creators and the reducer should reference the <code>LOGIN</code> and <code>LOGOUT</code> constants.");'
```
@ -45,9 +45,9 @@ tests:
<div id='jsx-seed'>
```jsx
// change code below this line
// измените код ниже этой линии
// change code above this line
// измените код выше этой линии
const defaultState = {
authenticated: false

View File

@ -4,14 +4,14 @@ title: Write a Counter with Redux
challengeType: 6
isRequired: false
videoUrl: ''
localeTitle: Напишите счетчик с Redux
localeTitle: Написание счетчика с помощью Redux
---
## Description
<section id="description"> Теперь вы узнали все основные принципы Redux! Вы видели, как создавать действия и создавать действия, создавать хранилище Redux, отправлять ваши действия против магазина и разрабатывать обновления состояния с помощью чистых редукторов. Вы даже видели, как управлять сложным состоянием с композицией редуктора и обрабатывать асинхронные действия. Эти примеры упрощены, но эти концепции являются основными принципами Redux. Если вы их хорошо понимаете, вы готовы приступить к созданию своего собственного приложения Redux. Следующие проблемы охватывают некоторые детали, касающиеся неизменности <code>state</code> , но сначала рассмотрим все, что вы изучили до сих пор. </section>
<section id="description"> Теперь вы узнали все основные принципы Redux! Вы видели, как создавать действия и создателей действия, создавать хранилище Redux, отправлять ваши действия в хранилище и разрабатывать обновления состояния с помощью чистых редукторов. Вы даже видели, как управлять сложным состоянием с композицией редукторов и обрабатывать асинхронные действия. Эти примеры упрощены, но эти концепции являются основными принципами Redux. Если вы их хорошо понимаете, вы готовы приступить к созданию своего собственного приложения Redux. Следующие упражнения охватывают некоторые детали, касающиеся неизменности <code>state</code> , но сначала рассмотрим все, что вы изучили до сих пор. </section>
## Instructions
<section id="instructions"> В этом уроке вы будете использовать простой счетчик с Redux с нуля. Основы представлены в редакторе кода, но вам нужно будет заполнить детали! Используйте имена, которые предоставляются и определяют <code>incAction</code> и <code>decAction</code> создателей действий, в <code>counterReducer()</code> , <code>INCREMENT</code> и <code>DECREMENT</code> типы действий, и , наконец, Redux <code>store</code> . После того, как вы закончите , вы должны быть в состоянии направить <code>INCREMENT</code> или <code>DECREMENT</code> действия для увеличения или уменьшения состояния проводится в <code>store</code> . Удачи в создании вашего первого приложения Redux! </section>
<section id="instructions"> В этом уроке вы будете реализовывать простой счетчик с помощью Redux с нуля. Основы представлены в редакторе кода, но вам нужно будет заполнить детали! Используйте имена, которые предоставлены и опишите создателей действий <code>incAction</code> и <code>decAction</code> , редуктор <code>counterReducer()</code> , типы действий <code>INCREMENT</code> и <code>DECREMENT</code> , и, наконец, Redux хранилище <code>store</code> . После того, как вы закончите , вы должны смочь отправить действия <code>INCREMENT</code> или <code>DECREMENT</code> для увеличения или уменьшения состояния в хранилище <code>store</code> . Удачи в создании вашего первого приложения Redux! </section>
## Tests
<section id='tests'>
@ -22,11 +22,11 @@ tests:
testString: 'assert(incAction().type ===INCREMENT, "The action creator <code>incAction</code> should return an action object with <code>type</code> equal to the value of <code>INCREMENT</code>");'
- text: Создатель действия <code>decAction</code> должен возвращать объект действия с <code>type</code> равным значению <code>DECREMENT</code>
testString: 'assert(decAction().type === DECREMENT, "The action creator <code>decAction</code> should return an action object with <code>type</code> equal to the value of <code>DECREMENT</code>");'
- text: Магазин Redux должен инициализировать с <code>state</code> 0.
- text: Хранилище Redux должно инициализироваться состоянием <code>state</code> равным 0.
testString: 'assert(store.getState() === 0, "The Redux store should initialize with a <code>state</code> of 0.");'
- text: Dispatching <code>incAction</code> в магазине Redux должен увеличивать <code>state</code> на 1.
- text: Отправка <code>incAction</code> в хранилище Redux должна увеличивать <code>state</code> на 1.
testString: 'assert((function() { const initialState = store.getState(); store.dispatch(incAction()); const incState = store.getState(); return initialState + 1 === incState })(), "Dispatching <code>incAction</code> on the Redux store should increment the <code>state</code> by 1.");'
- text: Отправка <code>decAction</code> в хранилище Redux должна <code>decAction</code> <code>state</code> на 1.
- text: Отправка <code>decAction</code> в хранилище Redux должна уменьшать <code>state</code> на 1.
testString: 'assert((function() { const initialState = store.getState(); store.dispatch(decAction()); const decState = store.getState(); return initialState - 1 === decState })(), "Dispatching <code>decAction</code> on the Redux store should decrement the <code>state</code> by 1.");'
- text: <code>counterReducer</code> должен быть функцией
testString: 'assert(typeof counterReducer === "function", "<code>counterReducer</code> should be a function");'
@ -41,16 +41,16 @@ tests:
<div id='jsx-seed'>
```jsx
const INCREMENT = null; // define a constant for increment action types
const DECREMENT = null; // define a constant for decrement action types
const INCREMENT = null; // определите константу для типа действия увеличения
const DECREMENT = null; // определите константу для типа действия уменьшения
const counterReducer = null; // define the counter reducer which will increment or decrement the state based on the action it receives
const counterReducer = null; // определите редуктор счётчика, который будет увеличивать или уменьшать состояние в зависимости от переданного действия
const incAction = null; // define an action creator for incrementing
const incAction = null; // определите создателя действия для увеличения
const decAction = null; // define an action creator for decrementing
const decAction = null; // определите создателя действия для уменьшения
const store = null; // define the Redux store here, passing in your reducers
const store = null; // определите хранилище Redux, передав в него ваши редукторы
```