ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React] How to stop refresh when submit form
    Frontend/maskeyes 2020. 3. 15. 03:11

    리엑트에서 form을 submit 했을때 페이지 재실행 되지 않고 비동기 작업을 하는 방법.

    먼저 나는 웹 개발 경험이 그렇게 많지 않다.

    그래서 필요에 의해 한번씩 개발을 하게 될때면, 검색을 최대한 활용한다.

     

    주소 검색 기능이 필요해서 작업 했던 과정(삽질?)을 남기고자한다.

     

     

    아래는 bootstrap을 이용해서 Navigation에 Form을 가져왔다.

     

    <Form inline onSubmit={searchAddress}>
    	<div>
    		<FormControl type="text" placeholder="주소 검색" className="mr-sm-1" name="inputAddress"  />
    		<Button variant="outlined" type="submit">이동</Button>
    	</div>
    </Form>

    여기서 시작이다.

    이동 버튼을 누르면 submit 이벤트가 발생해

    serachAddress 함수가 실행된다.

     

    searchAddress는 아래와 같이, 실행되면 input의 값을 dispatch 함수로 넘겨준다.

    searchAddress: (e) => {
        dispatch(mutations.searchAddress(e.target['inputAddress'].value));
    },

     

     

    발생된 Action을 saga가 캐치해 Acyncrouse 작업을 실행한다.

     

    비동기 작업은 fetch를 이용해 주소에 대한 정보를 가져오고,

    state를 업데이트해 해당 주소의 위치로(위경도) 지도를 이동시키고자 한다.

     

    그런데 fetch를 하는 과정에서 계속 실패를 했다.

     

    그래서 아래의 시도를 했다.

    1. request option을 변경하며 시도 -> 실패

    2. express로 호출 테스트 -> 성공

      but, react에서 express 호출해서 가져오기 -> 실패

    3. saga take -> takeEvery 사용 변경 -> 실패

    4. saga call() 사용 -> 실패

    5. fetch -> axios request 모듈 변경  -> 실패

    6. redux-form-saga 적용 -> 실패

    7.boilerplate 예제소스 실행해보기 -> refresh 안됨.. 그러나 다른점 찾기 실패

    ...

     

    몇 시간을 반복했는지 모르겠다.

    아무튼 결국 해결 했다.

    정답은 바로 'e.preventDefault();' 이거 한줄이다.

     

    해결하는 과정에서 한가지 단서를 찾았다.

    fetch실행시 yield를 하지 않고 반환 받았을 시 then절에서 결과값 '알림1'을 등록했다.

    그리고 fetch 바로 뒤에 '알림2'를 넣었다.

     

    이렇게 하고 실행을 하니, 알림1이뜨고 닫으면 fetch의 결과인 알림2가 출력됐다.

    그리고 알림을 닫으면 그 뒤 동작이 실행되지 않았다.

    이 과정에서 위와 같은 시도를 했고, 한참 지나서야 원인을 알게 됐다.

    다른 버튼들도 똑같은 구조인데 왜 검색폼만 안되는가 했는데,

    아주 기초적인걸 놓친것이었다.

     

    form의 경우 submit을 하면 주소항에 input값들을 쿼리로 넣어 리다이렉트한다.

    이 과정에서 페이지가 재시작(refresh) 된다.

    그래서 saga에서 비동기 작업이 이루워지다 페이지가 재시작되니 작업 context를 잃어버리는 것이다.

     

    아주 기초적인것을 큰 시간을 주고 배웠다..

    7의 과정에서 발견 할 수도 있었는데 놓치고 말았다.

    검색 과정에서도 계속 보였는데,, 

     

    아래와같이 preventDefault()를 해주면 페이지 재시작을 막을 수 있다.

    searchAddress: (e) => {
        e.preventDefault();
        dispatch(mutations.searchAddress(e.target['inputAddress'].value));
      },

    (더불어 e.stopPropagation() 함수를 사용하면 부모 엘리먼트로 이벤트가 전파되는 것을 막을 수 있다.)

     

     

     

     

     

     

     

     

    참고

    댓글

Designed by Tistory.