如何编写更新Redux商店的操作?

时间:2018-04-28 13:23:11

标签: react-redux

我有一个使用React-Redux的网络应用程序。有React表(列表),我需要填充数据库中的数据。我在服务器上使用WebApi并在客户端上自动生成(通过TypeWriter)web-api。代码的关键部分如下所示:

1)路由:

<Route path="/Dictionary/:dictionaryName" component={Dictionary} />

2)状态:

export type SingleDictionaryState = Readonly<{
    singleDictionary: WebApi.SingleDictionary[];
}>;

export const initialState: SingleDictionaryState = {
    singleDictionary: [],
};

3)减速器:

export const reducer: Reducer<SingleDictionaryState> = (state: SingleDictionaryState = initialState, action: AllActions): SingleDictionaryState => {
        switch (action.type) {
            case getType(actions.setSingleDictionaryValue):
                return { ...state, ...action.payload };
        }

        return state;
};

4)行动:

const actionsBasic = {
    setSingleDictionaryValue: createAction('singleDictionary/setSingleDictionaryValue', (singleDictionary: any) => singleDictionary),
};

const actionsAsync = {
    getDictionaryByName: (dictionaryName: string) => {
        const currentState = store.getState().singleDictionary;
        WebApi.api.dictionaryQuery.getDictionary(capitalizeForApi(dictionaryName));
    },
};

export const actions = Object.assign(actionsBasic, actionsAsync);

const returnsOfActions = Object.values(actionsBasic).map($call);
export type AllActions = typeof returnsOfActions[number];

5)容器:

const mapStateToProps = (state: AppState, ownProps: OwnProps): StateProps => ({
    dictionaryType: state.singleDictionary,
});

const mapDispatchToProps = (dispatch: Dispatch<any>): DispatchProps => ({
    onLoad: (dictionaryName: string) => {
        Actions.singleDictionary.getDictionaryByName(dictionaryName);
    },
});

export default withRouter(connect<StateProps, DispatchProps, OwnProps>(mapStateToProps, mapDispatchToProps)(DictionaryPage));

6)客户端web-api:

class DictionaryQueryService {

    getDictionary(name: string) {
        const user = store.getState().oidc.user;
        const headers = new Headers();
        headers.append('Accept', 'application/json');
        headers.append('Content-Type', 'application/json');
        headers.append('Cache-Control', 'no-cache, no-store, must-revalidate');
        headers.append('Pragma', 'no-cache');
        headers.append('Expires', '0');

        if (user) {
            headers.append('Authorization', `Bearer ${user.access_token}`);
        }

        return () => {
            return fetch(`api/dictionaries/${encodeURIComponent(name)}`, {
                method: 'get',
                headers,
            })
            .then(response => {
                    if (!response.ok) {
                        const traceId = response.headers.get("X-Trace-Id");
                        throw new ApiError(`${response.status} ${response.statusText}`, traceId);
                    }
                    return response.status == 204 ? null : response.json() as Promise<any[]>;
                 });
        };
    }

实际上,我不确定如何编写我的getDictionaryByName操作。

1 个答案:

答案 0 :(得分:0)

只需2美分。我使用ES6语法,但Typescript的工作方式类似。

actionTypes.js

export const RESET_DICTIONARIES = 'RESET_DICTIONARIES';
export const LOAD_DICTIONARIES_REQUEST = 'LOAD_DICTIONARIES_REQUEST';
export const LOAD_DICTIONARIES_REQUEST_SUCCESS = 'LOAD_DICTIONARIES_REQUEST_SUCCESS';
export const LOAD_DICTIONARIES_REQUEST_FAILURE = 'LOAD_DICTIONARIES_REQUEST_FAILURE';

dictionaryActions.js

/* Load Dictionariies*/
export function loadDictionariesRequestBegin() {
  return {type: types.LOAD_DICTIONARIES_REQUEST};
}

export function loadDictionariesRequest(name) {
  return function(dispatch) {
    dispatch(loadDictionariesRequestBegin());
    // eslint-disable-next-line no-undef
    const request = new Request(`${YOUR_URL}/api/dictionaries/{name}`, {
      method: 'get',
      headers: new Headers({
        'Content-type': 'application/json',
        'Accept': 'application/json',
        'Authorization': auth.getToken(),        
      })
    });

    return fetch(request)
      .then(        
        response => {
          if (!response.ok) {            
            dispatch(loadDictionariesRequestFailure(response.statusText));
            throw new Error(response.statusText);
          }
          return response.json();
        },
        error => {
          dispatch(loadDictionariesRequestFailure(error));
          throw error;
        })
      .then(dictionaries=> {
        if (dictionaries) {
          dispatch(loadDictionariesRequestSuccess(dictionaries));
          return dictionaries;
        } else {
          throw new Error('dictionaries NOT found in response');
        }
      });
  };
}

export function loadDictionariesRequestSuccess(dictionaries) {
  return {type: types.LOAD_DICTIONARIES_REQUEST_SUCCESS, dictionaries};
}

export function loadDictionariesRequestFailure(error) {
  return {type: types.LOAD_DICTIONARIES_REQUEST_FAILURE, error};
}

dictionaryReducer.js

export default function dictionaryReducer(state = initialState.dictionaries, action) {
  switch (action.type) {
    case types.RESET_DICTIONARIES:
      return {
        ...state,
        loaded: false,
        loading: false,
        error: null,
      };
    /* load dictionaries*/
    case types.LOAD_DICTIONARIES_REQUEST:
      return {
        ...state,
        error: null,        
        loaded: false,
        loading: true
      };
    case types.LOAD_DICTIONARIES_REQUEST_SUCCESS:
      return {
        ...state,
        data: action.dictionaries,
        error: null,
        loaded: true,
        loading: false
      };
    case types.LOAD_DICTIONARIES_REQUEST_FAILURE:
      return {
        ...state,
        loaded: false,
        loading: false,
        error: action.error
      };
  return state;
}

initialState.js

export default {
  actions: {},
  dictionaries: { 
    data: [],
    loaded: false,
    loading: false,
    error: null,      
  },
}

字典客户端API

this.props.actions
  .loadDictionaryRequest(name)
  .then(data => {
    this.setState({ data: data, errorMessage: '' });
  })
  .then(() => {
      this.props.actions.resetDictionaries();
  })
  .catch(error => {
    ...
  });

希望这可能会有所帮助。

相关问题