rhanziy

React Native - react hook form의 onsubmit에 파라미터로 입력값 넘기기!!! 본문

React Native

React Native - react hook form의 onsubmit에 파라미터로 입력값 넘기기!!!

rhanziy 2023. 12. 1. 15:58

화면 플로우 

1. 가게에 들어가 주문할 상품을 선택한다.

2. 선택한 상품 페이지에서 주문 정보 작성하기 버튼 클릭!

3. 관련 정보를 입력한다.

4. 주문 정보 확인 페이지에서 확인 후 결제로 이동

 

각 페이지가 1개씩 구현되어있고, 3번에서 입력한 정보를 4번 페이지에서 확인할 수 있어야 하기때문에

3번 페이지 입력form 값들을 onsubmit 요청을 하면 navigation에 태워 4번 페이지에 넘겨줘야하는 상황

 

 

3번 페이지 OrderInfoScreen (기능 외 나머지 코드는 생략했습니다.)

const OrderInfoScreen: React.FC = () => {

  const {pageMove, canSubmit, ...methods} = useOrderInfoForm(productId);

  return (
    <>
      <KeyboardAvoidingView sentry-label="OrderDetailScreen">
        <FormProvider {...methods}>
          
          <Form />

          <View style={styles.orderButton}>
            <Button
              onPress={pageMove}
              disabled={!canSubmit}
              >
              주문하기 버튼
            </Button>
          </View>
        </FormProvider>
      </KeyboardAvoidingView>
    </>
  );
};

입력폼 값을 canSubmit으로 검증하고~ 주문하기 버튼을 누르면 pageMove가 실행되는데,

 

useOrderInfoForm.ts(useForm)

const useOrderInfoForm = () => {

  const navigation = useMainStackNavigation();

  const goToOrderScreen = useCallback(
    (data: OrderReadyParams) => {
        navigation.navigate('OrderStack', {
          screen: 'OrderScreen',
          params: {
            orderInfo: data,
          },
        });
    },
    [navigation, user],
  );

  const {register, handleSubmit, watch, ...props} = useForm<OrderFormFields>({
    defaultValues: {
      OrderFormFeilds 타입의 자료 값 초기화
    },
  });

 
  const pageMove = handleSubmit(data => {
    goToOrderScreen(data);
  });

  return {
    register,
    pageMove,
    handleSubmit,
    watch,
    canSubmit,
    ...props,
  };
};

pageMove는 handleSubmit을 통해 입력 값들을 orderScreen의 파라미터로 넘겨보낸다.

(a태그나 submit타입 버튼의 경우 이벤트 외에 각자의 고유한 기능을 가지고있기 때문에 단순 데이터를 넘기기위해 handleSubmit을 사용했다.)

 

4번 페이지 OrderScreen

const OrderScreen: React.FC = () => {
  const {
    params: {orderInfo},
  } = useOrderStackRoute<'OrderScreen'>();
  
  const {onSubmit, ...methods} = useOrderForm(orderInfo);

  return (
    <>
      <KeyboardAvoidingView sentry-label="OrderDetailScreen">
        <FormProvider {...methods}>
          <OrderProduct id={orderInfo.productId} />
          <OrderInfo orderInfo={orderInfo} />
          <OrderAmount id={orderInfo.productId} quantity={orderInfo.quantity} />

          <View style={styles.orderButton}>
            <Button
              sentry-label="주문/결제하기 버튼"
              onPress={onSubmit}
              variant="filled"
              size="large"
              fillWidth>
              결제하기
            </Button>
          </View>
        </FormProvider>
      </KeyboardAvoidingView>
    </>
  );
};

useRoute를 통해 페이지의 파라미터로 orderInfo 를 넘겨주고, 그 데이터를 useOrderForm의 defaultValue에 박아넣어

페이지에 노출시켜준다. 

4페이지 OrderScreen의 onSubmit 버튼을 누르면 해당api로 값을 넘기는 코드 작성~

 

🔽useRoute?

더보기

react native에서 navigation을 사용해 페이지를 이동할 때, 이동할 페이지로 특정 데이터를 넘겨야할 때가 있다. 일반적으로 다른 컴포넌트에 데이터를 제공하는 방법은 크게 prop을 사용하는 방법과 전역상태를 설정해 공유하는 방법이 있는데, navigation을 사용할 때는 두가지 방법 모두 적절하지 않다.

navigation으로 이동 가능한 각 화면들은 모두 navigator라는 고차 컴포넌트에 묶여있기 때문에 직접적으로 prop을 전달할 수도 없을 뿐더러, state를 사용해 전달하려고 해도 prop드릴링, 또는 전역 상태 관리가 동반되어야한다. 또한 상태관리 라이브러리를 사용한다고 해도 하나의 페이지에서 다른 페이지로 일부 데이터를 넘기는데 매번 새로운 상태를 선언하고 클린업해주는 과정은 너무 과하다고 생각되기도 한다.

이럴 때 사용하는 것이 바로 useRoute라는 훅이다. 다른 페이지로 이동할 때 사용하는 navigate 함수와 useRoute를 사용하면 함수에 인자를 넘겨주듯이 다른 페이지로 데이터를 넘기고, 받을 수 있다.

 

 

일단은 이렇게 구현했다. 더 좋은 방법이 있을 것 같은데 궁리해봐야지.....

 

 

 

Comments