개발자

react-hook-form 및 react-table을 사용하면서 문제가 풀리지 않아서 질문드려요..

2024년 04월 26일조회 80

캠페인 데이터 안에 매체 데이터들이 있는데요. 매체 데이터의 이름으로 테이블을 만들고 테이블의 행을 클릭하면, 해당 행에 연관된 데이터를 보여주고, 수정이 가능한 폼?을 만들고있는데요. 캠페인 폼을 서브밋할 경우 매체에서 변경된 값은 정상적으로 콘솔에 찍히는데 테이블의 다른 매체를 선택해도 생성일이 변경되지 않는 문제가 있는데요.. 어떤게 문제인지 잘 모르겠습니다.. 첨부한 스크린샷에서 처럼 예를 들어.. 매체명11 - 생성일 5월1일 매체명22 - 생성일 5월2일 매체명33 - 생성일 5월3일... 이런식으로 데이터가 있다고하면 매체를 선택할때마다 생성일도 같이 변해야 되는데 변경이 안됩니다..ㅠ 폼 하나로 캠페인 및 캠페인 안에 있는 매체들의 데이터를 한번에 서브밋 하고싶어서 저런식으로 구성을했어요.. 뭐가 문제인지 도무지 모르겠어요.. 도와주세요!..

1const {
2      control,
3      handleSubmit,
4      register,
5      setValue
6    } = useForm<Campaign>({
7      defaultValues: campaign
8    });
9
10    const {
11      fields,
12      append,
13      remove
14    } = useFieldArray({
15      control,
16      name: 'medias'
17    });
18
19const mediasTable = useReactTable({
20      columns,
21      data: fields,
22      state: {
23        columnVisibility: { mediaId: false },
24        rowSelection: { 0: true }
25      },
26      getCoreRowModel: getCoreRowModel()
27    });
28
29<Grid item xs={8}>
30                  <Grid container spacing={1}>
31                    <Grid item xs={6}>
32                      <Controller
33                        name={`medias.${selectedIndex}.billDate`}
34                        control={control}
35                        render={({ field: { onChange, value } }) => (
36                          <DesktopDatePicker
37                            format="yyyy-MM-dd"
38                            value={value ? new Date(value) : null}
39                            onChange={(newValue) => {
40                              const formattedDate = newValue ? format(newValue, 'yyyy-MM-dd') : null;
41                              // @ts-ignore
42                              setValue('billDate', formattedDate);
43                              onChange(formattedDate || null); // 새로운 값이 있으면 그 값을, 없으면 null을 설정
44                            }}
45                            slotProps={
46                              {
47                                textField: {
48                                  label: '계산서 발행일',
49                                  fullWidth: true,
50                                  id: 'media-billDate'
51                                },
52                                actionBar: {
53                                  actions: ['clear']
54                                }
55                              }
56                            }
57                          />
58                        )}
59                      />
60                    </Grid>
61                  </Grid>
62                </Grid>
이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.
profile picture
익명님의 질문

답변 3

profile picture

익명

작성자

2024년 04월 26일

값은 실제로 서브밋할때 변경이 되지만, 화면상에서 다른 매체를 선택한 생성일로 표시가 안되는 문제입니다.ㅠ

profile picture

익명

작성자

2024년 04월 26일

useEffect(() => { if (selectedMedia && selectedMedia.billDate) { setValue(`medias.${selectedIndex}.billDate`, selectedMedia.billDate); } }, [selectedIndex, selectedMedia, setValue]); 이런식으로 선언을 하니깐, billDate는 변경이 되는데, 값이 10개 20개인 경우 일일히 하나씩 선언을 해줘야 하나요?... ㅠㅠ

profile picture

익명

작성자

2024년 04월 26일

아래 처럼 코드를 추가하니깐 테이블에서 매체를 선택할때마다 선택한 매체의 해당하는 값으로 변경이되고, 변경된 값도 적용이 잘 되는데, 초보자라 이게 맞는건지를 모르겠네요.. 도움 주실분 안계실까요?...

1type CampaignMediaKeys = keyof CampaignMedia;
2    type IndexedMediaKeys = `medias.${number}.${CampaignMediaKeys}`;
3
4    useEffect(() => {
5      if (selectedMedia) {
6        Object.entries(selectedMedia).forEach(([key, value]) => {
7          const fieldPath: IndexedMediaKeys = `medias.${selectedIndex}.${key}` as IndexedMediaKeys;
8          setValue(fieldPath, value);
9        });
10      }
11    }, [selectedMedia, selectedIndex, setValue]);
12
13이런 코드를 추가하고,
14
15<Controller
16                        name={`medias.${selectedIndex}.billDate`}
17                        control={control}
18                        render={({ field: { onChange, value } }) => (
19                          <DesktopDatePicker
20                            format="yyyy-MM-dd"
21                            value={value ? new Date(value) : null}
22                            onChange={(newValue) => {
23                              const formattedDate = newValue ? format(newValue, 'yyyy-MM-dd') : null;
24                              onChange(formattedDate || null); // 새로운 값이 있으면 그 값을, 없으면 null을 설정
25                              update(selectedIndex, { ...fields[selectedIndex], billDate:formattedDate!});
26                            }}
27                            slotProps={
28                              {
29                                textField: {
30                                  label: '계산서 발행일',
31                                  fullWidth: true,
32                                  id: 'media-billDate'
33                                },
34                                actionBar: {
35                                  actions: ['clear']
36                                }
37                              }
38                            }
39                          />
40                        )}
41                      />

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

AI 답변
커리어리 AI 봇 프로필 이미지

커리어리 AI 봇

GPT가 달아주는 답변입니다.

2024년 04월 26일

문제가 되는 부분은 `DesktopDatePicker`의 `onChange` 핸들러 내부에서, `setValue` 함수에 전달되는 필드 이름이 잘못된 것 같습니다. 현재 코드에서는 `setValue('billDate', formattedDate);`로 작성하셨는데, 이 부분을 `setValue(\`medias.${selectedIndex}.billDate\`, formattedDate);`와 같이 수정해야 할 것 같습니다. 즉, 'billDate'라는 이름의 필드 값만 바꾸려고 하지 말고, 선택된 미디어 인덱스에 연결된 'billDate' 필드 값을 변경해야 합니다. 수정 후 코드를 다시 실행해보시고, 여전히 문제가 해결되지 않으면 추가로 알려주세요!

목록으로

지금 가입하면 모든 질문의 답변을 볼 수 있어요!