[Formik] Formik Form 내부에서 사용한 state가 업데이트되지 않을 때

서해빈·2021년 5월 4일
0

Trouble

목록 보기
12/15

발단: Formik Form 내부에서 사용한 state 값이 업데이트되지 않음

Formik의 Form 내부의 컴포넌트에서 state값 careers을 사용했다. 그런데 해당 state값이 업데이트되었을 때 Formik의 initialValues는 정상적으로 갱신된 값이 할당되지만, 내부의 컴포넌트에서는 이전 state값을 그대로 사용하는 문제가 발생했다.

function CareersForm() {
  ...
  const [careers, setCareers] = useState([]);
  ...
  return (
    <>
      <Formik
        initialValues={ careers }
        ...
      >
        <Form>
          {careers.map((career, idx) => ( // 초기 careers 값으로 고정
            ...
          ))}
        </Form>
      </Formik>
    </>
  );
}

원인: Formik의 enableReinitialize 옵션

Formik은 기본적으로 enableReinitialize값이 false로 주어지는데, 이 때 form의 initialValues 값이 외부의 컴포넌트에 의해 할당된다면, initialValues 값이 변하지 않는 한 다시 렌더링하지 않는다. 이 때 initialValues의 변함을 체크하는데는 얕은 비교가 사용된다.

이 때 사용하던 state 변수 careers는 array였는데, setCareers() 함수로 업데이트할 때 careers 배열 객체에서 특정 요소를 추가하거나 제거하고 그 객체를 다시 반환하도록 되어있었다. 때문에 careers를 업데이트해도 Formik입장에서는 해당 객체의 주소가 같으므로 내부의 form을 다시 렌더링하지 않아서 발생한 문제였다.

해결: state 업데이트시 새로운 배열 객체를 반환

원인을 알고 나서는 enableReinitialize 옵션에 true값을 주면 해결이 될 줄 알았으나 반응이 없는 것은 마찬가지였다. 더 자세하게 찾아보기에는 이미 쏟은 시간이 너무 많아서 포기했다...ㅠ

차선책으로 setCareers() 함수에서 기존의 careers가 아닌 새로운 배열을 반환하도록 수정하니 Formik 내부의 form도 정상적으로 다시 렌더링되는 것을 확인할 수 있었다.

참고 및 출처

  • [Formik Docs] enableReinitialize - 바로가기
  • Formik does not re-render when initialValues change #811 - 바로가기

0개의 댓글