Railsベースのフォームの中に一部の入力欄でReactコンポーネントを使うことが稀にあるかもしれません。
入力欄がinvalidな状態なのに送信ボタンはReact外で困る。。。
そいういった時は、さくっと送信ボタンのDOMを探して操作しても良いですが、Rails自体(rails-ujs)の仕組みを利用することで再利用性が上がると思います。
以下のコード例のようにhookを作成し、Reactコンポーネントでのバリデーション状態を元に送信ボタンを有効化/無効化しています。(別にhooksじゃなくてnullを返すコンポーネントでももちろん良いです。)
import Rails from "@rails/ujs"
import { useEffect, useRef } from "react"
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} />
....
</>
)
}