[javascript] React redux에서 가져 오기 오류를 처리하는 가장 좋은 방법은 무엇입니까?

클라이언트 용 감속기가 하나 있고 AppToolbar 용 감속기가 하나 있고 다른 감속기가 있습니다.

이제 클라이언트를 삭제하기위한 가져 오기 작업을 생성했다고 가정 해 보겠습니다. 실패하면 Clients reducer에 몇 가지 작업을 수행해야하는 코드가 있지만 AppToolbar에 일부 전역 오류를 표시하고 싶습니다.

그러나 Clients와 AppToolbar 감속기는 상태의 동일한 부분을 공유하지 않으며 감속기에서 새 작업을 만들 수 없습니다.

그렇다면 전역 오류를 어떻게 표시한다고 가정합니까? 감사

업데이트 1 :

este devstack을 사용한다는 것을 언급하는 것을 잊었습니다.

업데이트 2 :
나는 Eric의 대답을 올바른 것으로 표시했지만 este에서 사용하는 솔루션은 Eric과 Dan의 대답의 조합과 비슷하다고 말해야합니다 … 코드에서 가장 적합한 것을 찾아야합니다 .. .



답변

“전역 오류”라는 개념을 errors원하면 addError, removeError 등의 작업을 수신 할 수있는 감속기를 만들 수 있습니다 . 그런 다음 Redux 상태 트리에 연결하여 state.errors적절한 곳에 표시 할 수 있습니다.

이 당신이 접근 할 수있는 여러 가지 방법이 있지만, 일반적인 생각은 글로벌 오류 / 메시지가 완전히 분리 살고 자신의 감속기를받을만한 것입니다 <Clients />/ <AppToolbar />. 물론 이러한 구성 요소 중 하나에 액세스해야하는 경우 필요한 곳에 소품으로 errors전달할 errors수 있습니다.

업데이트 : 코드 예

다음은 “전역 오류” errors를 최상위 수준으로 전달 <App />하고 조건부로 렌더링하는 경우 ( 오류가있는 경우) 어떻게 보일지에 대한 한 가지 예입니다 . react-redux를connect 사용 하여 <App />구성 요소를 일부 데이터에 연결합니다.

// App.js
// Display "global errors" when they are present
function App({errors}) {
  return (
    <div>
      {errors &&
        <UserErrors errors={errors} />
      }
      <AppToolbar />
      <Clients />
    </div>
  )
}

// Hook up App to be a container (react-redux)
export default connect(
  state => ({
    errors: state.errors,
  })
)(App);

그리고 액션 생성자에 관한 한 응답에 따라 성공 실패 ( redux-thunk )를 전달 합니다.

export function fetchSomeResources() {
  return dispatch => {
    // Async action is starting...
    dispatch({type: FETCH_RESOURCES});

    someHttpClient.get('/resources')

      // Async action succeeded...
      .then(res => {
        dispatch({type: FETCH_RESOURCES_SUCCESS, data: res.body});
      })

      // Async action failed...
      .catch(err => {
        // Dispatch specific "some resources failed" if needed...
        dispatch({type: FETCH_RESOURCES_FAIL});

        // Dispatch the generic "global errors" action
        // This is what makes its way into state.errors
        dispatch({type: ADD_ERROR, error: err});
      });
  };
}

감속기는 단순히 오류 배열을 관리하여 항목을 적절하게 추가 / 제거 할 수 있습니다.

function errors(state = [], action) {
  switch (action.type) {

    case ADD_ERROR:
      return state.concat([action.error]);

    case REMOVE_ERROR:
      return state.filter((error, i) => i !== action.index);

    default:
      return state;
  }
}


답변

Erik의 대답 은 정확하지만 오류를 추가하기 위해 별도의 작업을 수행 할 필요가 없다는 점을 추가하고 싶습니다. 다른 방법은 필드 와 함께 모든 작업error 을 처리하는 감속기를 사용하는 것 입니다 . 이것은 개인적인 선택과 관습의 문제입니다.

예를 들어, 오류 처리가있는 Redux real-world예제 에서 :

// Updates error message to notify about the failed fetches.
function errorMessage(state = null, action) {
  const { type, error } = action

  if (type === ActionTypes.RESET_ERROR_MESSAGE) {
    return null
  } else if (error) {
    return error
  }

  return state
}


답변

현재 몇 가지 특정 오류 (사용자 입력 유효성 검사)에 대해 취하고있는 접근 방식은 내 하위 감소 기가 예외를 발생시키고 루트 감속기에서이를 포착하여 작업 객체에 연결하도록하는 것입니다. 그런 다음 오류에 대한 작업 개체를 검사하고이 경우 오류 데이터로 상태 트리를 업데이트하는 redux-saga가 있습니다.

그래서:

function rootReducer(state, action) {
  try {
    // sub-reducer(s)
    state = someOtherReducer(state,action);
  } catch (e) {
    action.error = e;
  }
  return state;
}

// and then in the saga, registered to take every action:
function *errorHandler(action) {
  if (action.error) {
     yield put(errorActionCreator(error));
  }
}

그리고 상태 트리에 오류를 추가하는 것은 Erik이 설명하는 것과 같습니다.

나는 그것을 매우 드물게 사용하지만 합법적으로 감속기에 속하는 논리를 복제하지 않아도됩니다 (잘못된 상태로부터 스스로를 보호 할 수 있습니다).


답변

모든 API 관련 오류를 처리하기 위해 사용자 정의 미들웨어를 작성하십시오. 이 경우 코드가 더 깔끔해집니다.

   failure/ error actin type ACTION_ERROR

   export default  (state) => (next) => (action) => {

      if(ACTION_ERROR.contains('_ERROR')){

       // fire error action
        store.dispatch(serviceError());

       }
}


답변

내가하는 일은 효과별로 모든 오류 처리를 효과에 집중시키는 것입니다.

/**
 * central error handling
 */
@Effect({dispatch: false})
httpErrors$: Observable<any> = this.actions$
    .ofType(
        EHitCountsActions.HitCountsError
    ).map(payload => payload)
    .switchMap(error => {
        return of(confirm(`There was an error accessing the server: ${error}`));
    });


답변

axios HTTP 클라이언트를 사용할 수 있습니다. 이미 인터셉터 기능을 구현했습니다. 그때까지 요청이나 응답이 처리되기 전에 가로 챌 수 있습니다.

https://github.com/mzabriskie/axios#interceptors

// Add a request interceptor
axios.interceptors.request.use(function (config) {
    // Do something before request is sent
    return config;
  }, function (error) {
    // Do something with request error
    return Promise.reject(error);
  });

// Add a response interceptor
axios.interceptors.response.use(function (response) {
    // Do something with response data
    return response;
  }, function (error) {
    // Do something with response error
    return Promise.reject(error);
  });


답변