我正在清理從一開始就錯誤的減速機設置。我使用redux doco和the ducks pattern來設置它。設計/組合減速機減速機
我想單獨/分我的狀態像doco suggests:
{
domainData1 : {},
domainData2 : {},
appState1 : {},
appState2 : {},
ui : {
uiState1 : {},
uiState2 : {},
}
}
在我來說,我有一些專輯,目錄和照片,我正在努力進行管理。國家應該是這個樣子:
{
//domainData
albums : {...},
catalogs : {...},
photos : {...},
//appState
selectedAlbum : {...},
//uiState
ui : {
loading : {},
uiState2 : {},
}
}
我已經把屬於專輯的所有代碼在一個文件,其中的動作,動作的創造者,recuders和API位於 類似的目錄和照片。 然後我將reducer與combineReducers組合在一個單獨的文件中。下面
代碼...
我的問題是什麼?當我做的東西在專輯我會希望所有的域數據進入狀態的專輯分支。但我不希望UI和應用程序狀態的東西進入專輯分支 - 這應該進入應用程序和UI狀態分支。這是我的設置不可能的,例如當加載相冊時,我在「相冊」減速器中設置加載標誌,這是fedRed的combineReducer,結果是加載狀態成爲相冊分支的一部分狀態...
相冊模塊:
import { createRequest, responseHandler, notAuthorized } from './apiUtils';
import { List, Map, fromJS } from 'immutable';
//actions
const REQUEST_ALBUMS = 'REQUEST_ALBUMS';
const FETCH_ALBUMS_SUCCESS = 'FETCH_ALBUMS_SUCCESS';
const FETCH_ALBUM_SUCCESS = 'FETCH_ALBUM_SUCCESS';
const REQUEST_ALBUM = 'REQUEST_ALBUM';
const CREATE_ALBUM = 'CREATE_ALBUM';
const CREATE_ALBUM_SUCCESS = 'CREATE_ALBUM_SUCCESS';
const UPDATE_ALBUM = 'UPDATE_ALBUM';
const UPDATE_ALBUM_SUCCESS = 'UPDATE_ALBUM_SUCCESS';
// Reducer
var init = Map(fromJS({
albums: [],
album: [],
loading: false,
}));
var newState = null;
export function reducer(state=init, action={}) {
switch (action.type) {
case FETCH_ALBUMS_SUCCESS: {
newState = state
.set('albums', fromJS(action.payload.albums))
.set('loading', false);
return newState;
}
case REQUEST_ALBUMS: {
return state.set('loading', true);
}
case FETCH_ALBUM_SUCCESS: {
newState = state
.set('album', fromJS(action.payload.album))
.set('loading', false);
return newState;
}
case REQUEST_ALBUM: {
return state.set('loading', true);
}
case CREATE_ALBUM: {
return state.set('loading', true);
}
case CREATE_ALBUM_SUCCESS: {
newState = state
.set('album', fromJS(action.payload.album))
.set('loading', false);
return newState;
}
case UPDATE_ALBUM: {
return state.set('loading', true);
}
case UPDATE_ALBUM_SUCCESS: {
newState = state
.set('album', fromJS(action.payload.album))
.set('loading', false);
return newState;
}
}
return state;
}
// Action Creators
export function getAlbumsPending(response) {
return {
type: REQUEST_ALBUMS,
};
}
export function getAlbumsSuccess(response) {
return {
type: FETCH_ALBUMS_SUCCESS,
payload: response,
};
}
export function getAlbumPending(response) {
return {
type: REQUEST_ALBUM,
};
}
export function getAlbumSuccess(response) {
return {
type: FETCH_ALBUM_SUCCESS,
payload: response,
};
}
function createAlbumPending(response) {
return {
type: CREATE_ALBUM,
};
}
function createAlbumSuccess(response) {
return {
type: CREATE_ALBUM_SUCCESS,
payload: response,
};
}
export function updateAlbumPending(response) {
return {
type: UPDATE_ALBUM,
};
}
export function updateAlbumSuccess(response) {
return {
type: UPDATE_ALBUM_SUCCESS,
payload: response,
};
}
//API
export function fetchAlbums() {
//API url
const url = '/api/albums.json';
//make the call
return dispatch => {
dispatch(getAlbumsPending());
fetch(createRequest('GET', url, null))
.then(response => responseHandler(response))
.then(data => dispatch(getAlbumsSuccess(data)))
.catch(error => console.log('request failed', error));
};
}
export function fetchAlbum(id) {
//url
var url = '/api/albums/'.concat(id);
return dispatch => {
dispatch(getAlbumPending());
fetch(createRequest('GET', url, null))
.then(response => responseHandler(response))
.then(data => dispatch(getAlbumSuccess({ album: data })))
.catch(error => console.log('request failed', error));
};
}
export function createAlbum(params) {
//API url
const url = '/api/albums/';
return dispatch => {
dispatch(createAlbumPending());
fetch(createRequest('POST', url, params))
.then(response => responseHandler(response))
.then(data => dispatch(createAlbumSuccess({ album: data })))
.catch(error => console.log('request failed', error));
};
}
export function updateAlbum(params) {
//API url
var url = '/api/albums/'.concat(params.id);
//make the call
return dispatch => {
dispatch(updateAlbumPending());
fetch(createRequest('PUT', url, params))
.then(response => responseHandler(response))
.then(data => dispatch(updateAlbumSuccess({ album: data })))
.catch(error => console.log('request failed', error));
};
}
CombineRecucer:
import { combineReducers } from 'redux';
import { reducer as albumReducer } from '../actions/album';
import { reducer as catalogReducer } from '../actions/catalog';
export default combineReducers({
albums: albumReducer, // <- loading flag ends up here
catalogs: catalogReducer,
loading: // I want loading flag here
});
很抱歉的長期職位 - 沒有土豆
您必須在'loading'減速器中添加'case UPDATE_ALBUM:'東西。您可以從其他鴨文件中導入動作類型。專輯reducer只負責更新自己的狀態片。多個減速器可以監聽相同的動作類型,並對其自己的片進行一些更改。 –
OMG ...那麼簡單..我完全錯過了redux的天才...... @HåkenLid提出了一個答案,所以我可以信任你 – martin
當然。我已經添加了答案。 –