Cách xử lý lỗi chính xác trong React-Redux


11

Tôi muốn hiểu cách xử lý lỗi chung chung hoặc chính xác hơn với React-Redux.

Giả sử, tôi có thành phần đăng ký số điện thoại.

Thành phần đó sẽ báo lỗi nếu số điện thoại đầu vào không hợp lệ

Điều gì sẽ là một cách tốt nhất để xử lý lỗi đó?

Ý tưởng 1: Tạo một thành phần, trong đó có lỗi và gửi một hành động bất cứ khi nào một lỗi được chuyển đến nó

ý tưởng 2: Vì lỗi liên quan đến thành phần đó, hãy chuyển lỗi đó đến một thành phần (không được kết nối với redux, tức là thành phần xử lý lỗi sẽ không gửi hành động)

Câu hỏi: Ai đó có thể hướng dẫn tôi cách xử lý lỗi thích hợp trong React-Redux cho ứng dụng quy mô lớn không?


1
Làm thế nào để xác thực số điện thoại xảy ra, đồng bộ hoặc không đồng bộ, sau khi người dùng làm điều gì đó hoặc ngay lập tức? Những gì bạn muốn xảy ra, hiển thị cho người dùng? Redux là để lưu trữ trạng thái của ứng dụng của bạn, có vẻ như một chút không liên quan đến câu hỏi của bạn.
RemcoGerlich

Câu trả lời:


3

Tôi muốn nói rằng cả hai ý tưởng ban đầu của bạn đều không chụp được toàn bộ bức tranh. Ý tưởng 1 chỉ là một cuộc gọi lại. Nếu bạn muốn sử dụng một cuộc gọi lại : useCallback. Ý tưởng 2 sẽ hoạt động và tốt hơn nếu bạn không cần sử dụng redux. Đôi khi, bạn nên sử dụng redux. Có thể bạn đang thiết lập tính hợp lệ của biểu mẫu bằng cách kiểm tra không có trường đầu vào nào có lỗi hoặc tương tự. Vì chúng ta đang ở chủ đề redux, chúng ta hãy giả sử như vậy.

Thông thường cách tiếp cận tốt nhất để xử lý lỗi với redux là có một trường lỗi ở trạng thái sau đó được chuyển đến một thành phần lỗi.

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

Thành phần lỗi không phải chỉ hiển thị một lỗi, nó cũng có thể gây ra tác dụng phụ useEffect.

Làm thế nào lỗi được đặt / hủy đặt tùy thuộc vào ứng dụng của bạn. Hãy sử dụng ví dụ số điện thoại của bạn.

1. Nếu kiểm tra tính hợp lệ là một hàm thuần túy, nó có thể được thực hiện trong bộ giảm tốc.

Sau đó, bạn sẽ đặt hoặc hủy đặt trường lỗi để phản hồi các hành động thay đổi số điện thoại. Trong một bộ giảm tốc được xây dựng với một câu lệnh chuyển đổi, nó có thể trông như thế này.

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

2. Nếu lỗi được báo cáo bởi phụ trợ, hãy gửi các hành động lỗi.

Giả sử bạn đang gửi số điện thoại đến một phụ trợ xác thực trước khi nó thực hiện điều gì đó với số đó. Bạn không thể biết liệu dữ liệu có hợp lệ ở phía máy khách không. Bạn sẽ phải lấy từ của máy chủ cho nó.

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],
);

Bộ giảm tốc sau đó sẽ đưa ra một thông báo thích hợp cho lỗi và đặt nó.

Đừng quên bỏ đặt lỗi. Bạn có thể bỏ đặt lỗi trên một hành động thay đổi hoặc khi thực hiện một yêu cầu khác tùy thuộc vào ứng dụng.

Hai cách tiếp cận tôi vạch ra không loại trừ lẫn nhau. Bạn có thể sử dụng cái đầu tiên để hiển thị các lỗi có thể phát hiện cục bộ và cũng có thể sử dụng lỗi thứ hai để hiển thị phía máy chủ hoặc lỗi mạng.


Tôi rất đánh giá cao phản ứng của bạn và điều này chắc chắn có vẻ là một cách tiếp cận tốt hơn so với những gì tôi làm. Tôi vẫn đang tìm kiếm thêm một số gợi ý và do đó tôi đã bắt đầu một tiền thưởng cho câu hỏi này.
anny123

1

Tôi sẽ sử dụng một formik với xác nhận yup. sau đó, đối với lỗi phía máy chủ tôi sẽ sử dụng một cái gì đó như thế này:

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

Trông anerco thú vị, Cảm ơn bạn đã trả lời :)
anny123

1

Nó phụ thuộc vào loại xử lý lỗi mà bạn đang nói về. Nếu đó chỉ là hình thức xử lý xác thực thì tôi không nghĩ bạn cần Redux cho điều đó - vui lòng đọc bài viết này . Nếu lỗi của bạn chỉ được "tiêu thụ" trong thành phần đó, tại sao lại gửi nó đến redux? Bạn có thể dễ dàng sử dụng trạng thái địa phương của bạn cho điều đó.

Mặt khác, nếu bạn muốn hiển thị một số loại thông báo lỗi cho người dùng cho biết liệu có bất kỳ cuộc gọi HTTP nào trên trang web bị lỗi hay không, bạn có thể có lợi với việc chuyển hướng bằng cách gửi lỗi từ tất cả các phần trong ứng dụng của bạn (hoặc nói chung là phần mềm trung gian của bạn)

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
}

Bạn cần xác định trạng thái của bạn sẽ được tổ chức như thế nào và liệu bạn có cần đặt một số trạng thái trong redux hay chỉ giữ nó ở trạng thái cục bộ của thành phần của bạn. Bạn có thể đặt mọi thứ vào redux, nhưng cá nhân tôi muốn nói đó là một sự quá mức - tại sao bạn lại đặt trạng thái X trong thành phần Y nếu chỉ thành phần Y quan tâm đến trạng thái đó? Nếu bạn cấu trúc mã của mình một cách chính xác, bạn không nên gặp vấn đề với việc chuyển trạng thái đó từ cục bộ sang chuyển hướng sau này, nếu vì lý do nào đó, các phần khác trong ứng dụng của bạn bắt đầu phụ thuộc vào trạng thái đó.


1

Tôi nghĩ về nó như thế này, những gì nên được nhà nước? Và những gì nên được bắt nguồn từ nhà nước? Trạng thái nên được lưu trữ trong redux, và các đạo hàm nên được tính toán.

Số điện thoại là trạng thái, trường nào có trọng tâm là trạng thái, nhưng liệu nó có hợp lệ hay không, có thể được lấy từ các giá trị ở trạng thái.

Tôi sẽ sử dụng Reselect để dẫn xuất bộ đệm và trả về kết quả tương tự khi trạng thái có liên quan chưa được sửa đổi.

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

Sau đó, bạn có thể sử dụng bộ chọn trong mapStateToProps trong tất cả các thành phần có thể quan tâm đến giá trị này và bạn cũng có thể sử dụng nó trong các hành động không đồng bộ. Nếu tiêu điểm không thay đổi hoặc giá trị của trường không thay đổi, thì sẽ không xảy ra tính toán lại, nó sẽ trả về giá trị trước đó.

Tôi đang thêm kiểm tra trạng thái đã chọn chỉ để cho biết có bao nhiêu phần trạng thái có thể kết hợp với nhau để tạo ra một dẫn xuất.

Cá nhân tôi cố gắng tiếp cận mọi thứ bằng cách giữ cho trạng thái của mình nhỏ nhất có thể. Chẳng hạn, giả sử bạn muốn tạo lịch của riêng mình. Bạn sẽ lưu trữ mỗi ngày trong trạng thái, hoặc bạn chỉ cần biết một vài điều như năm và tháng hiện tại đang được xem. Chỉ với 2 phần trạng thái này, bạn có thể tính toán số ngày hiển thị trên lịch và không cần tính toán lại cho đến khi một trong số chúng thay đổi và việc tính toán lại này sẽ diễn ra gần như tự động, không cần phải suy nghĩ về tất cả các cách mà chúng có thể thay đổi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.