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