ReactコンポーネントからRailsのフォームの送信ボタンを無効化する
Railsベースのフォームの中に一部の入力欄でReactコンポーネントを使うことが稀にあるかもしれません。
入力欄がinvalidな状態なのに送信ボタンはReact外で困る。。。
そいういった時は、さくっと送信ボタンのDOMを探して操作しても良いですが、Rails自体(rails-ujs)の仕組みを利用することで再利用性が上がると思います。
以下のコード例のようにhookを作成し、Reactコンポーネントでのバリデーション状態を元に送信ボタンを有効化/無効化しています。(別にhooksじゃなくてnullを返すコンポーネントでももちろん良いです。)
import Rails from "@rails/ujs" import { useEffect, useRef } from "react" /** Railsのフォームの送信ボタンを@rails/ujsを使って有効/無効化します */ export const useRailsFormValidation = (valid: boolean) => { const containerRef = useRef<HTMLInputElement>(null) useEffect(() => { if (!containerRef.current) return const form = containerRef.current.form valid ? Rails.enableElement(form) : Rails.disableElement(form) }, [valid]) return { containerRef, } }
使用時はこんな感じ
const VeryComplexInput: React.FC<...> = props => { const { valid, onChange, value, ..... } = useSomeForm({...}) // フォームのイベントハンドリングをしていると想定 const { containerRef } = useRailsFormValidation(valid) return ( <> <input type="hidden" ref={containerRef} /> // フォームを探すためのinput .... </> ) }