在 API 次调用时响应本机屏幕导航

React Native screen navigation on API calls

所以,我已经反应了很长时间了。我在处理 API 并使其与移动应用程序中的小部件交互时遇到问题。

我想做什么?

我在屏幕 (A) 上,单击按钮后我转到屏幕 (B)。简单的。现在在屏幕 (B) 中,我填写了一个表格并提交。在提交表单时,我必须显示一个 Loading 组件。最后,如果请求是“成功”或“失败”,API 会做出响应。

如果成功 - 导航回屏幕 (A) 并在屏幕 (A) 上显示敬酒消息 (Boom..boom..)。

如果失败 - 在屏幕 (B) 中并显示 toast 消息(是的,带有失败消息)。

我的方法

让我们从减速器开始。我有以下减速器状态 -

{
    forSubmitRequest: false, // false - API has been trigerred to submit form
    formSubmitRequestOver: true, // true - request is over
    formSubmitRequestStatus: true // true - success
}

现在我的操作如下-

    case FORM_SUBMIT_REQUEST:
      return {
        ...state,
        formSubmitRequest: true,
        formSubmitRequestOver: false,
        formSubmitRequestStatus: false,
      };
    case FORM_SUBMIT_REQUEST_SUCCESS:
      return {
        ...state, 
        formSubmitRequestOver: true, 
        formSubmitRequestStatus: true
      };
    case FORM_SUBMIT_REQUEST_FAILED:
      return {
        ...state,
        formSubmitRequestOver: true,
        formSubmitRequestStatus: false,
      };
    case FORM_SUBMIT_REQUEST_DOWN:
      return {
        ...state, 
        formSubmitRequest: false, 
        formSubmitRequestOver: true
      };

这是我在 Screen(B) 中的编码逻辑

const [formSubmitReq, setFormSubmitReq] = useState(false);
const [showErrorFormSubmitToast, setShowErrorFormSubmitToast] = useState(false);


useEffect(() => {
  if (showErrorFormSubmitToast) {
    Toast.show({
      type: 'error',
      text1: 'Error',
      text2: 'Could not submit.',
      topOffset: ResponsiveSize(0),
      onHide: () => {
        setShowErrorFormSubmitToast(false);
      },
    });
  }
}, [showErrorFormSubmitToast]);

if (
  formSubmitReq &&
  props.teacher.formSubmitRequest &&
  !props.teacher.formSubmitRequestOver
) {
  return <Loading msg="Submitting form..." />;
}
if (
  formSubmitReq &&
  props.teacher.formSubmitRequest &&
  props.teacher.formSubmitRequestOver
) {
  if (props.teacher.formSubmitRequestStatus) {
    props.navigation.goBack();
    return <></>;
  } else {
    setFormSubmitReq(false);
    setShowErrorFormSubmitToast(true);
    props.handleCreateFormSubmitDown();
  }
}

画面逻辑(A)

const [showSuccessFormSubmitToast, setShowSuccessFormSubmitToast] =
    useState(false);

  useEffect(() => {
    if (showSuccessFormSubmitToast) {
      Toast.show({
        type: 'success',
        text1: 'Success',
        text2: 'Successfully submitted.',
        onHide: () => {
          setShowSuccessFormSubmitToast(false);
        },
      });
    }
  }, [showSuccessFormSubmitToast]);

  if (
    !showSuccessFormSubmitToast &&
    props.teacher.formSubmitRequest &&
    props.teacher.formSubmitRequestOver &&
    props.teacher.formSubmitRequestStatus
  ) {
    console.log('Prep show toast');
    setShowSuccessFormSubmitToast(true);
    props.handleCreateFormSubmitDown();
  }

最后这个函数 - handleCreateFormSubmitDown 只是触发动作 - FORM_SUBMIT_REQUEST_DOWN

代码要点 ->

我试图仅在请求成功且实际触发请求时才在屏幕 (A) 上显示 Toast。请求成功并且我回到屏幕(A)现在我只是导航到屏幕(B)可能不会发生,所以我必须确保吐司不可见,因为请求没有被触发。现在,当 reducer 状态更新时,Screen(A) 也会被渲染,导致一些糟糕的事情。

任何人都可以指出他们在这种情况下遵循的策略以及我可以在这里改进的地方吗?

一种方法是利用 route params from react-navigation

在屏幕 B

...
useEffect(() => {
  // Navigate to screen A with a route param
  navigation.navigate(A, { displaySuccessToast: true });

}, [showSuccessFormSubmitToast])

在屏幕 A 中

...
useEffect(() => {
  if (route.params.displaySuccessToast) {
    Toast.show({
        type: 'success',
        text1: 'Success',
        text2: 'Successfully submitted.',
        onHide: () => {
          // Hide Toast Action
        },
      });
  }
}, [route.params]);

否则,您可以使用全局状态管理解决方案,例如 redux

同理。您需要更新全局状态中的标志。然后导航到前面的屏幕并检查是否设置了此标志并呈现 toast 消息。