React Hooks でフォームデータ (multipart/form-data
)を POST したいけど、いまいち参考例がなかったので、作ってみたというメモ。
といってもやり方は普通に useSWR
や useFetch
とかと同じ感じかな。
React Hooks 自体はこんな感じ
import axios from "axios"; import { useCallback, useState } from "react"; type State<TResponse, TError> = { response: TResponse | null; error: TError | null; loading: boolean; }; type Args = { url: string; } const useForm = <TRequest extends Record<string, unknown>, TResponse, TError = unknown>({ url }: Args) => { const [state, setState] = useState<State<TResponse, TError>>({ response: null, error: null, loading: false }); const submit = useCallback((payload: TRequest) => { setState({ ...state, loading: true }); const form = new FormData(); for (const key of Object.keys(payload)) { form.append(key, payload[key]); } axios.post(url, form, { headers: { "content-type": "multipart/form-data" } }).then((w) => { const response = w.data as TResponse; setState({ ...state, response, loading: false }); }).catch((err) => { const error = err as TError; setState({ ...state, error, loading: false}); }); }, [url]); return { ...state, submit } as const; } export default useForm;
使う側的にはこんな感じかな:
import React from "react"; type Props = {}; const SomeForm: React.FC<Props> = () => { const { response, error, loading, submit } = useForm({ url: "/api/submit" }); const onClickSubmit = () => { submit({ key: "value" }); }; return ( <div> <button onClick={onClickSubmit}>送信</button> { loading && <p>送信中だよ!</p>} { response && <p>成功したよ!</p>} { error && <p>エラーだよ!</p>} </div> ); };
簡単ですね。
ということで、メモでした。