微调加载Redux

问题描述:

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 
    } 
    } 
}; 

貌似错误的做法

如果你只是想知道如果的请求待处理并且什么方法(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