有关Redux状态更新和API调用的建议

时间:2017-09-21 21:16:23

标签: reactjs react-redux

更新我的应用程序状态,然后在我的应用程序状态更新时进行API调用的最佳方法是什么。

我有一个应用程序在我传入应用程序级别对象的地方进行API调用。

这是我的容器方法,它调用两个动作。第一个更新我将用于进行api调用的搜索条件。问题是当我进行fetchActivityData调用时,应用程序状态没有更新。

//container.js
 clickHandler(){
    this.props.setActivityId(this.props.activity.id); 
    this.props.fetchActivityData(this.props.searchCriteria);
} 

.......

function mapDispatchToProps(dispatch){
    return bindActionCreators({ setActivityId, fetchActivityData }, 
dispatch);
}

function mapStateToProps(state) {
    return { 
        searchCriteria: state.searchCriteria
    };
}

然后我有一群动作创建者来更新我的API调用标准

//criteria_actions.js
export function setActivityId(activityId){
return {
    type: SET_ACTIVITY_ID,
    payload: activityId
  }
}

export function setSort(sort){
   return {
     type: SET_SORT,
     payload: sort
  }
 }

export function setSortOrder(sortOrder){
    return {
       type: SET_SORT_ORDER,
       payload: sortOrder
   }
 }

这是标准动作减速器:

export default function(state = initialCriteria, action) {
switch(action.type) {
    case SET_ACTIVITY_ID: {
        return {...state, activityId: action.payload};
    }
    case SET_SORT: {
        return {...state, sort: action.payload};
    }
    case SET_SORT_ORDER: {
        return {...state, sortOrder: action.payload};
    }
    case SET_SEARCH_TERMS: {
        return {...state, searchTerms: action.payload};
    }
    case INCREMENT_PAGE: {
        return {...state, page: state.page+1 };
    }
    case SET_PAGESIZE: {
        return {...state, pagesize: action.payload};
    }
    default:
        return state;
}
}

然后我有一个动作创建者进行API调用

//api_action
export function fetchActivityData(searchCriteria) {
const { activityId, sort, sortOrder, searchTerms, page, pagesize } = searchCriteria;
var otherFilters = "";

if(activityId === 7){
    otherFilters = '"media": "all"';
}

const request = axios({
    method: 'get',
    url: `${API_ROOT}/activities/campaigns/${PROJECT_ID}/sort/${sort}/sortorder/${sortOrder}/page/${page}/pagesize/${pagesize}/?filter={"at":[${activityId}],"search":"${searchTerms}",${otherFilters}}`,
    headers: {
      "USER_TOKEN": USER_TOKEN,
    }
  });

return {
    type: FETCH_ACTIVITY_DATA,
    payload: request
}
}

这是我的API减速机

export default function(state = [], action) {
switch(action.type) {
    case FETCH_ACTIVITY_DATA:
        return action.payload.data.data.items;
    default:
        return state;
}
}

1 个答案:

答案 0 :(得分:1)

你忽略了问题最重要的方面; setActivityIdfetchActivityData如何相关?您提到setActivityId对后来使用的fetchActivityData输入有一些影响,但这有什么影响?这是你的代码中存在真正问题的部分。

更一般地说;

Redux操作应该反映用户的抽象操作。理想情况下,用户操作应直接映射到redux操作。

但是,行动本身可能非常复杂。如果将它们包装在可由Redux Thunk使用的函数中,则操作甚至可以由其他操作组成。 E.g;

someUserAction(input) {
    return (dispatch, getState) {
        dispatch(anotherAction(input));
        dispatch(aThirdAction(input));
    }
}

这是在没有更多知识的情况下,很难将最佳实践应用于您的案例。根据您提供的信息,我认为解决方案看起来像这样:

export function setActivityIdAndFetch(activityId){
    return (dispatch, getState) {
        dispatch(setActivityId(activityId));

        let searchCriteria = //some derived value
        dispatch({
            type: SET_SEARCH_CRITERIA,
            payload: searchCriteria
        });

        dispatch(fetchActivityData(searchCriteria));
    }
}

值得注意的是,我会将searchCriteria设置移动到它自己的调度。我怀疑你当前正在减速器中获取这个值,但是这个逻辑应该存在于动作创建器中,正是出于这些目的。