В моем веб-приложении я хочу получить URL-адреса из API. Также я хочу получить категории для этих предметов.
index.js:
componentDidMount () {
this.props.fetchUrls();
this.props.fetchCategories();
}
Сначала я получаю URL-адреса вот так:
export const fetchUrlsSuccess = urls => ({
type: FETCH_URLS_SUCCESS,
payload: { urls }
});
export const fetchUrls = () => dispatch => {
dispatch(fetchUrlsBegin());
return fetch(`${api}/urls`)
.then(handleErrors)
.then(res => res.json())
.then(json => {
dispatch(fetchUrlsSuccess(json));
return json.urls;
})
.catch(error => dispatch(fetchUrlsFailure(error)));
};
выборка категорий:
export const fetchCategoriesSuccess = categories => ({
type: FETCH_CATEGORIES_SUCCESS,
payload: { categories }
});
export const fetchCategoriesFailure = error => ({
type: FETCH_CATEGORIES_FAILURE,
payload: { error }
});
export function fetchCategories() {
return dispatch => {
dispatch(fetchCategoriesBegin());
return fetch(`${api}/categories`)
.then(handleErrors)
.then(res => res.json())
.then(json => {
dispatch(fetchCategoriesSuccess(json));
return json.categories;
})
.catch(error => dispatch(fetchCategoriesFailure(error)));
};
}
URL-редуктор:
import {
FETCH_URLS_BEGIN,
FETCH_URLS_SUCCESS,
FETCH_URLS_FAILURE
} from "../actions/types";
export default function urlReducer(state = [], action) {
switch (action.type) {
case FETCH_URLS_BEGIN:
console.log("url fetch begin", state);
return {
...state,
loading: true,
error: null
};
case FETCH_URLS_SUCCESS:
console.log("url fetch success", state);
return {
...state,
loading: false,
items: action.payload.urls
};
case FETCH_URLS_FAILURE:
console.log("url fetch error", state);
return {
...state,
loading: false,
error: action.payload.error,
items: []
};
default:
return state;
}
}
категории редуктора:
import {
FETCH_CATEGORIES_BEGIN,
FETCH_CATEGORIES_SUCCESS,
FETCH_CATEGORIES_FAILURE
} from "../actions/types";
export default function categoriesReducer(state = [], action) {
switch (action.type) {
case FETCH_CATEGORIES_BEGIN:
console.log("categories fetch begin", state);
return {
...state,
loading: true,
error: null
};
case FETCH_CATEGORIES_SUCCESS:
console.log("categories fetch success", state);
return {
...state,
loading: false,
items: action.payload.categories
};
case FETCH_CATEGORIES_FAILURE:
console.log("categories fetch fail", state);
return {
...state,
loading: false,
error: action.payload.error,
items: []
};
default:
return state;
}
}
объединение редукторов в индексе редукторов:
import { combineReducers } from "redux";
import urlReducer from "./urlReducer";
import categoriesReducer from "./categoriesReducer";
import modalReducer from "./modalReducer";
export default combineReducers({
urls: urlReducer,
modal: modalReducer,
categories: categoriesReducer
});
создать магазин:
import { createStore, applyMiddleware, compose } from "redux";
import { persistStore, persistReducer } from "redux-persist";
import thunk from "redux-thunk";
import storage from "redux-persist/lib/storage";
import rootReducer from "../reducers";
const persistConfig = {
key: "root",
storage
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
const middleware = [thunk];
let store = createStore(
persistedReducer,
compose(
applyMiddleware(...middleware),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
);
let persistor = persistStore(store);
export { store, persistor };
Для категорий я делаю то же самое. Затем я объединяю оба редуктора.
Что происходит, так это то, что гос.урлы. Элементы перезаписываются, а вместо этого state.categories.items хранит состояние. Я не понимаю почему.
вывод избыточного dev-инструмента после второй выборки:
![https://i.stack.imgur.com/UQsHQ.png](https://i.stack.imgur.com/UQsHQ.png)
Я довольно новичок в редуксе и не понимаю управления состоянием ...