React-Redux의 올바른 오류 처리 방법


11

React-Redux를 사용하는 것이 더 일반적이거나 올바른 오류 처리 방법을 이해하고 싶습니다.

전화 번호 가입 구성 요소가 있다고 가정합니다.

입력 전화 번호가 유효하지 않은 경우 구성 요소에서 오류가 발생합니다

그 오류를 처리하는 가장 좋은 방법은 무엇입니까?

아이디어 1 : 오류가 발생하여 오류가 전달 될 때마다 작업을 전달하는 구성 요소 만들기

아이디어 2 : 오류가 해당 구성 요소와 관련되어 있으므로 해당 오류를 구성 요소에 전달하십시오 (이 구성 요소는 redux에 연결되지 않았습니다.

질문 : 누군가 대규모 앱을위한 React-Redux의 오류 처리 방법을 안내해 줄 수 있습니까?


1
사용자가 무언가를 또는 즉시 수행 한 후 전화 번호의 유효성 검사는 어떻게 동기식 또는 비동기식입니까? 사용자가 볼 수있는 일이 무엇입니까? Redux는 앱의 상태를 저장하기위한 것으로, 질문과 관련이없는 것 같습니다.
RemcoGerlich

답변:


3

나는 당신의 초기 아이디어 중 어느 것도 전체 그림을 포착하지 못한다고 말할 것입니다. 아이디어 1은 단지 콜백입니다. 콜백을 사용하려는 경우 : useCallback. 아이디어 2가 작동하며 redux를 사용할 필요가없는 경우 바람직합니다. 때로는 redux를 사용하는 것이 좋습니다. 입력 필드에 오류나 유사한 것이 없는지 확인하여 양식 유효성을 설정하고있을 수 있습니다. 우리는 redux 주제에 관한 것이기 때문에 그것이 사실이라고 가정합시다.

일반적으로 redux를 사용하여 오류를 처리하는 가장 좋은 방법은 오류 필드를 상태에두고 오류 구성 요소로 전달하는 것입니다.

const ExampleErrorComponent= () => {
  const error = useSelector(selectError);
  if (!error) return null;
  return <div className="error-message">{error}</div>;
}

오류 구성 요소는 오류를 표시하지 않아도되며 부작용도 발생할 수 있습니다 useEffect.

오류 설정 / 설정 해제 방법은 응용 프로그램에 따라 다릅니다. 전화 번호 예를 사용하겠습니다.

1. 유효성 검사가 순수한 기능인 경우 감속기에서 수행 할 수 있습니다.

그런 다음 전화 번호 변경 작업에 대한 응답으로 오류 필드를 설정하거나 설정 해제합니다. switch 문으로 작성된 감속기에서는 다음과 같이 보일 수 있습니다.

case 'PHONE_NUMBER_CHANGE':
  return {
    ...state,
    phoneNumber: action.phoneNumber,
    error: isValidPhoneNumber(action.phoneNumber) ? undefined : 'Invalid phone number',
  };

2. 백엔드에서 오류가보고되면 오류 조치를 전달하십시오.

전화 번호를 전화 번호로 전송하기 전에 유효성 검사를 수행하는 백엔드로 전화 번호를 보내고 있다고 가정 해 봅시다. 클라이언트 측에서 데이터가 유효한지 알 수 없습니다. 서버의 단어를 가져 가면됩니다.

const handleSubmit = useCallback(
  () => sendPhoneNumber(phoneNumber)
    .then(response => dispatch({
      type: 'PHONE_NUMBER_SUBMISSION_SUCCESS',
      response,
    }))
    .catch(error => dispatch({
      type: 'PHONE_NUMBER_SUBMISSION_FAILURE',
      error,
    })),
  [dispatch, phoneNumber],
);

감속기는 오류에 대한 적절한 메시지를 표시하고 설정해야합니다.

오류를 설정 해제하는 것을 잊지 마십시오. 변경 조치 또는 애플리케이션에 따라 다른 요청을 할 때 오류를 설정 해제 할 수 있습니다.

내가 설명한 두 가지 접근법은 상호 배타적이지 않습니다. 첫 번째를 사용하여 로컬로 감지 가능한 오류를 표시하고 두 번째를 사용하여 서버 측 또는 네트워크 오류를 표시 할 수 있습니다.


귀하의 답변에 감사 드리며 이것이 내가하는 일에 비해 확실히 더 나은 접근법으로 보입니다. 나는 아직도 더 많은 제안을 찾고 있으므로이 질문에 현상금을 시작했습니다.
anny123

1

yup 유효성 검사와 함께 formik를 사용합니다. 그런 다음 서버 측 오류의 경우 다음과 같이 사용합니다.

import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { Spinner } from "@blueprintjs/core";

export default ({ action, selector, component, errorComponent }) => {
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(action());
  }, [dispatch, action]);

  const DispatchFetch = () => {
    const { data, isRequesting, error } = useSelector(selector());
    if (!isRequesting && data) {
      const Comp = component;
      return <Comp data={data}></Comp>;
    } else if (error) {
      if (errorComponent) {
        const ErrorComp = errorComponent;
        return <ErrorComp error={error}></ErrorComp>;
      }
      return <div>{error}</div>;
    }
    return <Spinner></Spinner>;
  };

  return <DispatchFetch></DispatchFetch>;
};

흥미로운 anerco가 보인다, 답장을 보내 주셔서 감사합니다 :)
anny123

1

어떤 종류의 오류 처리에 대해 이야기하고 있습니까? 양식 유효성 검사 처리 만하면 Redux가 필요하지 않다고 생각합니다 . 이 기사 를 읽으십시오 . 해당 구성 요소 내에서만 오류가 "소비"될 경우 왜 redux로 보냅니 까? 이를 위해 로컬 상태를 쉽게 사용할 수 있습니다.

반면, 사이트의 HTTP 호출이 실패했는지 여부를 나타내는 일종의 오류 알림을 사용자에게 표시하려면 응용 프로그램의 모든 부분 (또는 일반적으로 미들웨어)에서 오류를 발송하여 redux를 사용하면 이점을 얻을 수 있습니다

dispatch({ type: 'SET_ERROR_MESSAGE', error: yourErrorOrMessage });

// simple error message reducer
function errorMessage(state = null, action) {
  const { type, error } = action;

  switch (type) {
      case 'RESET_ERROR_MESSAGE':
          return null;
      case 'SET_ERROR_MESSAGE':
          return error;
  }

  return state
}

상태 구성 방법과 일부 상태를 redux로 설정해야하는지 아니면 구성 요소의 로컬 상태로 유지해야하는지 정의해야합니다. 모든 것을 redux에 넣을 수는 있지만 개인적으로 과잉이라고 말하고 싶습니다. 구성 요소 Y만이 상태에 관심이 있다면 왜 구성 요소 Y에 상태 X를 넣을까요? 코드를 올바르게 구성하면 나중에 해당 상태를 로컬에서 redux로 옮기는 데 문제가 없어야합니다. 어떤 이유로 앱의 다른 부분이 해당 상태에 의존하기 시작합니다.


1

나는 이것에 대해 생각합니다. 상태는 무엇입니까? 그리고 국가에서 무엇을 얻어야합니까? 상태는 redux에 저장하고 파생을 계산해야합니다.

전화 번호는 상태이며 초점이있는 필드는 상태이지만 유효한지 여부에 따라 상태의 값에서 파생 될 수 있습니다.

Reselect를 사용하여 파생을 캐시하고 관련 상태가 수정되지 않은 경우 동일한 결과를 반환합니다.

export const showInvalidPhoneNumberMessage = createSelector(
  getPhoneValue,
  getFocusedField,
  (val, focus) => focus !== 'phone' && val.length < 10 // add other validations.
)

그런 다음이 값을 염려 할 수있는 모든 구성 요소에서 mapStateToProps의 선택기를 사용하고 비동기 작업에도 사용할 수 있습니다. 포커스가 변경되지 않았거나 필드의 값이 변경되지 않은 경우 재 계산이 발생하지 않고 대신 이전 값을 반환합니다.

선택한 상태 확인을 추가하여 여러 상태 조각이 어떻게 결합하여 하나의 파생을 얻을 수 있는지 보여줍니다.

나는 개인적으로 상태를 최대한 작게 유지하여 사물에 접근하려고합니다. 예를 들어, 자신 만의 달력을 만들고 싶다고 가정 해 봅시다. 매일 매일 주에 보관 하시겠습니까, 아니면 현재보고있는 현재 연도 및 월과 같은 몇 가지 사항 만 알아야합니까? 이 두 가지 상태만으로 달력에 표시 할 요일을 계산할 수 있으며 그 중 하나가 변경 될 때까지 다시 계산할 필요가 없으며이 계산은 사실상 자동으로 수행되므로 가능한 모든 방법에 대해 생각할 필요가 없습니다. 변화.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.