2016-03-04 150 views
3

Redux中做某種旋轉指示器的理想方式是什麼?微調加載Redux

假設我有一個名爲Things的REST API。在React組件中,我有Thing Card,Thing Card ListAdd Thing Form

如果我想編一個微調,每次我做什麼是理想的方式:從服務器 *)GET Things從服務器 *)PUT Thing/123服務器 *)DELETe Thing/123 *)POST Thing服務器

我知道這個想法在Redux Store中設置了一個叫做isPending: true的狀態。

這是我

store = { 
    things: { 
    data: [], // array of things 
    isPending: true, 
    isSuccess: false, 
    isError: false, 
    error: undefined 
    } 
}; 

然而,這isPending: true是什麼動作?得到?放?刪除? POST?如果我將所有這些動作都依賴於同一個屬性isPending: true,那麼奇怪的事情就會開始發生,比如=>當我做一個POST Things時,isPending是真實的,而其他依賴於該屬性的組件也顯示他們的微調者。

這裏是我的代碼

import _ from 'lodash'; 
import Api from '../../utils/api'; 

export const thingApi = new Api({ 
    url: '/api/things', 
    token: localStorage.getItem('token') 
}); 

// ------------------------------------ 
// Constants 
// ------------------------------------ 
export const GET_THING_PENDING = 'GET_THING_PENDING'; 
export const GET_THING_SUCCESS = 'GET_THING_SUCCESS'; 
export const GET_THING_FAILURE = 'GET_THING_FAILURE'; 
export const POST_THING_PENDING = 'POST_THING_PENDING'; 
export const POST_THING_SUCCESS = 'POST_THING_SUCCESS'; 
export const POST_THING_FAILURE = 'POST_THING_FAILURE'; 
export const DELETE_THING_PENDING = 'DELETE_THING_PENDING'; 
export const DELETE_THING_SUCCESS = 'DELETE_THING_SUCCESS'; 
export const DELETE_THING_FAILURE = 'DELETE_THING_FAILURE'; 

// ------------------------------------ 
// Actions 
// ------------------------------------ 
export const getThing =() => { 
    return (dispatch, getState) => { 
    dispatch(getThingPending()); 
    return thingApi.get() 
     .then(({ data }) => { 
     dispatch(getThingSuccess(data)); 
     }) 
     .catch(({ error }) => { 
     dispatch(getThingFailure(error)); 
     }); 
    }; 
}; 

export const postThing = ({ name }) => { 
    return (dispatch, getState) => { 
    dispatch(postThingPending()); 
    const body = { name }; 
    return thingApi.post({ data: body }) 
     .then(({ data }) => { 
     dispatch(postThingSuccess(data)); 
     }) 
     .catch(({ error }) => { 
     dispatch(postThingFailure(error)); 
     }); 
    }; 
}; 

export const deleteThing = (_id) => { 
    return (dispatch, getState) => { 
    dispatch(deleteThingPending()); 
    return thingApi.delete({ 
     url: `/api/things/${_id}` 
    }).then((res) => { 
     dispatch(deleteThingSuccess(_id)); 
     }) 
     .catch(({ error }) => { 
     dispatch(deleteThingPending(error)); 
     }); 
    }; 
}; 

export const getThingPending =() => ({ 
    type: GET_THING_PENDING 
}); 

export const getThingSuccess = (things) => ({ 
    type: GET_THING_SUCCESS, 
    payload: things 
}); 

export const getThingFailure = (error) => ({ 
    type: GET_THING_FAILURE, 
    payload: error 
}); 

export const postThingPending =() => ({ 
    type: POST_THING_PENDING 
}); 

export const postThingSuccess = (thing) => ({ 
    type: POST_THING_SUCCESS, 
    payload: thing 
}); 

export const postThingFailure = (error) => ({ 
    type: POST_THING_FAILURE, 
    payload: error 
}); 

export const deleteThingPending =() => ({ 
    type: DELETE_THING_PENDING 
}); 

export const deleteThingSuccess = (_id) => ({ 
    type: DELETE_THING_SUCCESS, 
    payload: _id 
}); 

export const deleteThingFailure = (error) => ({ 
    type: DELETE_THING_FAILURE, 
    payload: error 
}); 

export const actions = { 
    getThing, 
    getThingSuccess, 
    postThing, 
    postThingSuccess, 
    deleteThing, 
    deleteThingSuccess 
}; 

// ------------------------------------ 
// Action Handlers 
// ------------------------------------ 
const ACTION_HANDLERS = { 
    [GET_THING_PENDING] (state, action) { 
    return { 
     isPending: true, 
     isSuccess: false, 
     isFailure: false 
    }; 
    }, 

    [GET_THING_SUCCESS] (state, { payload: data }) { 
    return { 
     isPending: false, 
     isSuccess: true, 
     data, 
     isFailure: false 
    }; 
    }, 

    [GET_THING_FAILURE] (state, { payload: error }) { 
    return { 
     isPending: false, 
     isSuccess: false, 
     isFailure: true, 
     error 
    }; 
    }, 

    [POST_THING_PENDING] (state, action) { 
    return { 
     isPending: true, 
     isSuccess: false, 
     isError: false 
    }; 
    }, 

    [POST_THING_SUCCESS] (state, { payload: data }) { 
    debugger; 
    return { 
     isPending: false, 
     isSuccess: true, 
     data: [ ...state.data, data ], 
     isError: false 
    }; 
    }, 

    [POST_THING_FAILURE] (state, { payload: error }) { 
    return { 
     isPending: false, 
     isSuccess: false, 
     isFailure: true, 
     error 
    }; 
    }, 

    [DELETE_THING_PENDING] (state, action) { 
    return { 
     ...state, 
     isPending: true, 
     isSuccess: false, 
     isFailure: false 
    }; 
    }, 

    [DELETE_THING_SUCCESS] ({ data }, { payload: _id }) { 
    const index = _.findIndex(data, (d) => d._id === _id); 

    const newData = [ 
     ...data.slice(0, index), 
     ...data.slice(index + 1) 
    ]; 

    return { 
     isPending: false, 
     isSuccess: true, 
     data: newData, 
     isFailure: false 
    }; 
    }, 

    [DELETE_THING_FAILURE] (state, { payload: error }) { 
    return { 
     isPending: false, 
     isSuccess: false, 
     isFailure: true, 
     error 
    }; 
    } 

}; 

// ------------------------------------ 
// Reducer 
// ------------------------------------ 
const initialState = { 
    isPending: false, 
    isSuccess: false, 
    data: [], 
    isFailure: false, 
    error: undefined 
}; 

export default function thingReducer (state = initialState, action) { 
    const handler = ACTION_HANDLERS[action.type]; 

    return handler ? handler(state, action) : state; 
} 

所以,我該怎麼辦,如果我需要代表微調(或錯誤)爲每個動作?

我應該做這樣的事情

store = { 
    things: { 
    get: { 
     data: [], 
     isPending, 
     isError, 
     isSuccess, 
     error 
    }, 
    post: { 
     data: [], 
     isPending, 
     isError, 
     isSuccess, 
     error 
    }, 
    put: { 
     data: [], 
     isPending, 
     isError, 
     isSuccess, 
     error 
    }, 
    delete: { 
     data: [], 
     isPending, 
     isError, 
     isSuccess, 
     error 
    } 
    } 
}; 

貌似錯誤的做法

回答

2

如果你只是想知道如果的請求待處理並且什麼方法(GET/POST/PUT /刪除)正在使用,您可以將方法類型與其餘狀態一起存儲,例如:

{ 
    data: [], 
    isPending: true, 
    method: 'POST', 
    isSuccess: false, 
    isError: false, 
    error: undefined 
} 

然後你就可以在你的組件檢查它,e.g:

const { isPending, method } = this.state; 

if (isPending && method === 'POST') { 
    // Do your thing 
} 

你可能不應該使用的方法類型的字符串,但 - 用一個常量。

+0

哦哇,這是完全有道理.......這樣一個明顯的解決方案!從來沒有想過它!謝謝! –

+0

很高興幫助!如果沒有其他東西,請標記爲正確。 – tobiasandersen