176 lines
6.6 KiB
Markdown
176 lines
6.6 KiB
Markdown
![]() |
---
|
|||
|
id: 5a24c314108439a4d4036154
|
|||
|
title: Об'єднати множинні зменшувачі
|
|||
|
challengeType: 6
|
|||
|
forumTopicId: 301436
|
|||
|
dashedName: combine-multiple-reducers
|
|||
|
---
|
|||
|
|
|||
|
# --description--
|
|||
|
|
|||
|
Коли стан вашого додатку стає більш складним, спокусливіше було б розділити стан на кілька частин. Замість цього запам'ятайте перший принцип Redux: весь стан програми відбувається в одному об'єкті стану, в сховищі. Тому, Redux забезпечує зменшення поєднання як рішення складного стану моделі. Ви визначаєте декілька знижень, щоб працювати з різними частинами вашого стану програм, і потім складаєте ці зменшувачі разом в одному кореневому варіанті. Кореневий варіант передається в Rudex за допомогою `createStore()` методу.
|
|||
|
|
|||
|
Для того, щоб дозволити нам комбінувати декілька скорочень разом, Redux надає `combineReducers()` метод. Цей метод приймає об'єкт як аргумент, в якому ви зазначаєте властивості, які пов'язують ключі з конкретними зменшувальними функціями. Назва, яку ви даєте ключам, буде використовуватися Redux як назва для відповідного фрагменту стану.
|
|||
|
|
|||
|
Як правило, для кожної частини програми корисно створити скорочення якщо вони різні або унікальні. Наприклад, у сповіщенні за допомогою автентифікації користувачів, один лічильник може обробляти автентифікацію, поки інший обробляє текст і замітки, які користувач надсилає. Для такої програми ми могли б написати метод `combineReducers()` на зразок цього:
|
|||
|
|
|||
|
```js
|
|||
|
const rootReducer = Redux.combineReducers({
|
|||
|
auth: authenticationReducer,
|
|||
|
notes: notesReducer
|
|||
|
});
|
|||
|
```
|
|||
|
|
|||
|
Тепер для доступу `notes` буде встановлено весь режим, пов'язаний з нашими нотатками та оброблено нашими `notesReducer`. Ось так можна скласти кілька скорочень для керування більш складним станом програми. У цьому прикладі, стан, утриманий у сховищі Redux, буде єдиним об'єктом, що містить `auth` і `notes` властивостей.
|
|||
|
|
|||
|
# --instructions--
|
|||
|
|
|||
|
Існує `counterReducer()` і `authReducer()` функції, які надані в текстовому редакторі, а також Redux сховищі. Завершіть запис функції `rootReducer()` за допомогою методу `Redux.combineReducers()`. Призначте `counterReducer` під назвою `count` і `authReducer` до ключа під назвою `auth`.
|
|||
|
|
|||
|
# --hints--
|
|||
|
|
|||
|
Код `counterReducer` повинен збільшити а `state` зменшити.
|
|||
|
|
|||
|
```js
|
|||
|
assert(
|
|||
|
(function () {
|
|||
|
const initialState = 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 === initialState + 2 && secondState === firstState - 1;
|
|||
|
})()
|
|||
|
);
|
|||
|
```
|
|||
|
|
|||
|
Код `authReducer` повинен переключити `state` `authenticated` між `true` і `false`.
|
|||
|
|
|||
|
```js
|
|||
|
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;
|
|||
|
})()
|
|||
|
);
|
|||
|
```
|
|||
|
|
|||
|
У сховищі `state` має бути два ключі: `count` який містить номер і `auth`, який містить об'єкт. `auth` повинен мати властивість `authenticated`, який містить логічне значення.
|
|||
|
|
|||
|
```js
|
|||
|
assert(
|
|||
|
(function () {
|
|||
|
const state = store.getState();
|
|||
|
return (
|
|||
|
typeof state.auth === 'object' &&
|
|||
|
typeof state.auth.authenticated === 'boolean' &&
|
|||
|
typeof state.count === 'number'
|
|||
|
);
|
|||
|
})()
|
|||
|
);
|
|||
|
```
|
|||
|
|
|||
|
`rootReducer` повинен бути функцією, що поєднує `counterReducer` і `authReducer`.
|
|||
|
|
|||
|
```js
|
|||
|
(getUserInput) =>
|
|||
|
assert(
|
|||
|
(function () {
|
|||
|
const noWhiteSpace = __helpers.removeWhiteSpace(getUserInput('index'));
|
|||
|
return (
|
|||
|
typeof rootReducer === 'function' &&
|
|||
|
noWhiteSpace.includes('Redux.combineReducers')
|
|||
|
);
|
|||
|
})()
|
|||
|
);
|
|||
|
```
|
|||
|
|
|||
|
# --seed--
|
|||
|
|
|||
|
## --seed-contents--
|
|||
|
|
|||
|
```js
|
|||
|
const INCREMENT = 'INCREMENT';
|
|||
|
const DECREMENT = 'DECREMENT';
|
|||
|
|
|||
|
const counterReducer = (state = 0, action) => {
|
|||
|
switch(action.type) {
|
|||
|
case INCREMENT:
|
|||
|
return state + 1;
|
|||
|
case DECREMENT:
|
|||
|
return state - 1;
|
|||
|
default:
|
|||
|
return state;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
const LOGIN = 'LOGIN';
|
|||
|
const LOGOUT = 'LOGOUT';
|
|||
|
|
|||
|
const authReducer = (state = {authenticated: false}, action) => {
|
|||
|
switch(action.type) {
|
|||
|
case LOGIN:
|
|||
|
return {
|
|||
|
authenticated: true
|
|||
|
}
|
|||
|
case LOGOUT:
|
|||
|
return {
|
|||
|
authenticated: false
|
|||
|
}
|
|||
|
default:
|
|||
|
return state;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
const rootReducer = // Define the root reducer here
|
|||
|
|
|||
|
const store = Redux.createStore(rootReducer);
|
|||
|
```
|
|||
|
|
|||
|
# --solutions--
|
|||
|
|
|||
|
```js
|
|||
|
const INCREMENT = 'INCREMENT';
|
|||
|
const DECREMENT = 'DECREMENT';
|
|||
|
|
|||
|
const counterReducer = (state = 0, action) => {
|
|||
|
switch(action.type) {
|
|||
|
case INCREMENT:
|
|||
|
return state + 1;
|
|||
|
case DECREMENT:
|
|||
|
return state - 1;
|
|||
|
default:
|
|||
|
return state;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
const LOGIN = 'LOGIN';
|
|||
|
const LOGOUT = 'LOGOUT';
|
|||
|
|
|||
|
const authReducer = (state = {authenticated: false}, action) => {
|
|||
|
switch(action.type) {
|
|||
|
case LOGIN:
|
|||
|
return {
|
|||
|
authenticated: true
|
|||
|
}
|
|||
|
case LOGOUT:
|
|||
|
return {
|
|||
|
authenticated: false
|
|||
|
}
|
|||
|
default:
|
|||
|
return state;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
const rootReducer = Redux.combineReducers({
|
|||
|
count: counterReducer,
|
|||
|
auth: authReducer
|
|||
|
});
|
|||
|
|
|||
|
const store = Redux.createStore(rootReducer);
|
|||
|
```
|