input tag가 늘어나도 적용될 수 있는 form 작성
// useRef를 이용해서 이렇게도 작성할 수 있다 ㄷ ㄷ;;
// 참고해서 앞으로 하는 프로젝트에 적용해보기
// FormContext.js
import { useRef, useCallback, useContext, createContext } from "react";
const FormContext = createContext(null);
function useForm() {
const formRef = useRef({});
const handleSubmit = useCallback(
(callback) => (e) => {
e.preventDefault();
callback(formRef.current);
},
[formRef.current]
);
const register = useCallback(
(label) => {
console.log('등록된 라벨 : ', label)
const onChange = e => {
formRef.current = {
...formRef.current,
[label]: e.target.value
}
}
return {
onChange,
name: label
}
},
[]
);
return { register, handleSubmit };
}
export function useFormContext() {
const context = useContext(FormContext);
if (!context) {
throw new Error("Use FormContext inside provider.");
}
return context;
}
export function FormProvider({ children }) {
const formControls = useForm();
return (
<FormContext.Provider value={formControls}>{children}</FormContext.Provider>
);
}
// Form.js
import React from "react";
import { useFormContext } from "./FormContext";
export function Form({ children, onSubmit }) {
const { handleSubmit } = useFormContext();
return <form onSubmit={handleSubmit(onSubmit)}>{children}</form>;
}
export function TextInput({ label, ...props }) {
const { register } = useFormContext();
return <input type="text" {...register(label)} {...props} />;
}
export function SubmitButton({ children }) {
return <button type="submit">{children}</button>;
}
import React, { useState, useCallback } from "react";
import { FormProvider } from "./FormContext";
import { Form, TextInput, SubmitButton } from "./Form";
export default function DynamicFormApp() {
const [result, setResult] = useState(undefined)
const handleSubmit = useCallback((data) => {
setResult(data)
}, []);
return (
<>
<FormProvider>
<Form onSubmit={handleSubmit}>
<TextInput label="test-input-1" placeholder="Test input." />
<TextInput label="test-input-2" placeholder="Test input." />
<TextInput label="test-input-3" placeholder="Test input." />
<TextInput label="test-input-4" placeholder="Test input." />
<SubmitButton>Submit</SubmitButton>
</Form>
</FormProvider>
{result && (
<pre>
<code>{JSON.stringify(result, null, 2)}</code>
</pre>
)}
</>
);
}