質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

Q&A

解決済

1回答

2358閲覧

[react-hook-form] ラジオボタンのフォームから受け取るdataの値がUndefinedになってしまう

Chihiro

総合スコア2

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

0グッド

2クリップ

投稿2023/01/08 07:52

react-hook-formを使用してラジオボタンのインプットフォームを作成しています。
ラジオボタンの○ぽちを見えなくして、アイコンの画像をボタン代わりに使用したいのですが、以下の問題があり実装できていません。

1. CSSでdisplay:noneとすると、データの値がundefinedになってしまいます。このdisplay:noneの設定なしだと問題なくvalueが送信できます。
2. 同じく、アイコンをクリックすると(checked)ボーダーがアイコン周りに付くようにCSS設定しているのですが、display:noneのスタイルありでは機能せず、display:noneスタイルなしでは問題なく機能します。

お知恵を貸していただけますと幸いです。

実現したいこと

  • ラジオボタンのまるポチを非表示にし、かつフォームが機能(undefinedでないdata valueを送信する、checkできる)するようにする

イメージ説明

発生している問題・エラーメッセージ

現状エラーメッセージなどはありません。

該当のソースコード

3つのコンポーネントから成り立っています。

CustomRadioBtn.module.css

tsx

1.radioInput + .radioLabel:before{ 2 content: ""; 3 display: inline-block; 4 background-size: contain; 5 width: 140px; 6 height: 140px; 7} 8 9.radioLabel { 10 border-radius: 10px; 11 color: gray; 12 cursor: pointer; 13 margin: auto; 14 position: relative; 15 text-align: center; 16 transition: 0.5s; 17} 18 19.radioInput[value="slept less than 7hrs"]+.radioLabel:before{ 20 background-image: url(../../../public/images/sleep/lessThan7hrs.png); 21} 22.radioInput[value="slept more than 7hrs"]+.radioLabel:before{ 23 background-image: url(../../../public/images/sleep/moreThan7hrs.png); 24} 25 26/* below styling is not working */ 27.radioInput:checked + .radioLabel::before{ 28 border: 3px solid #000; 29} 30.radioInput{ 31 display: none; 32}

CustomeIconContainer.tsx

tsx

1import { Controller, useForm } from "react-hook-form"; 2import styled from "styled-components"; 3import CustomIconInputForm from "../molecules/CustomIconInputForm"; 4import StyledFlexboxRow from "components/layouts/Flexbox/StyledFlexboxRow"; 5 6type Tdata = { 7 sleep?: string; 8 stool?: string; 9 movement?: string; 10}; 11 12interface IContainerProps { 13 name: string; 14 options: string[]; 15 desc: string; 16 iconLog?: TIconValueData; 17} 18 19export type TIconValueData = { 20 id?: number; 21 sleep?: string; 22 movement?: string; 23 stool?: string; 24}; 25 26/** 27 * CustomIconContainer - handle icon input 28 */ 29const CustomIconContainer = (props: IContainerProps) => { 30 31 const { name, options, desc } = props; 32 const { handleSubmit, control } = useForm(); 33 34 const onSubmit = (data: Tdata) => { 35 if (data === undefined) { 36 throw new Error("your log is undefined"); 37 } 38 39 console.log(data); 40 }; 41 42 const StyledLabel = styled.label` 43 display: block; 44 `; 45 46 return ( 47 <div className="CustomIconContainer"> 48 <form onSubmit={handleSubmit(onSubmit)}> 49 <StyledLabel>{desc}</StyledLabel> 50 {/* mapping icon buttons */} 51 <StyledFlexboxRow> 52 {options.map((option, index) => ( 53 <Controller 54 key={index} 55 name={name} 56 control={control} 57 render={({ field: { onChange, ref, ...props } }) => ( 58 <CustomIconInputForm 59 {...props} 60 onChange={onChange} 61 value={option} 62 inputRef={ref} 63 desc={option} 64 /> 65 )} 66 /> 67 ))} 68 </StyledFlexboxRow> 69 <button type="submit">Save</button> 70 </form> 71 </div> 72 ); 73}; 74export default CustomIconContainer;

CustomIconInputForm.tsx

tsx

1import { IconDefinition } from "@fortawesome/fontawesome-common-types"; 2import { RefCallBack } from "react-hook-form"; 3import styles from "./CustomRadioBtn.module.css"; 4 5interface ICustomIconProps { 6 onChange?: () => void; 7 name?: string; 8 value?: string; 9 icon?: IconDefinition; 10 desc: string; 11 inputRef?: RefCallBack; 12} 13 14const CustomIconInputForm = (props: ICustomIconProps) => { 15 16 const { name, onChange, inputRef, value } = props; 17 18 const onChangeHandler = () => { 19 if (value !== undefined) { 20 onChange && onChange(); 21 } 22 }; 23 return ( 24 <span className="CustomIconInputForm"> 25 <input 26 ref={inputRef} 27 name={name} 28 value={value} 29 onChange={() => { 30 onChangeHandler; 31 }} 32 type="radio" 33 {...props} 34 className={styles.radioInput} 35 /> 36 37 <label htmlFor={name} className={styles.radioLabel}> 38 </label> 39 </span> 40 ); 41}; 42export default CustomIconInputForm;

試したこと

下記の対応をしてみたのですが変化ありませんでした。

  • Font Awesomeではなく画像ダウンロードに切り替えた。
  • styled.componentからcss moduleに切り替えた。

上記から、CSSではなさそうな気がします。おそらくreact-hook-formだと思うのですが、どこが抜けているのかまだ掴めていません。

補足情報(FW/ツールのバージョンなど)

Nextjs: "13.1.1"
react-hook-form: "^7.41.1"

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

display none を使わずに動いた例です

tsx

tsx

1 2import axios from "axios"; 3import ImageRadioCss from "./ImageRadio.module.css"; 4 5import { useForm } from "react-hook-form"; 6import { useState } from 'react' 7 8const ImageRadio = () => { 9 const { register, handleSubmit } = useForm(); 10 11 const items = ["item1", "item2"] 12 const [selectedItem, setItem] = useState(""); 13 14 const requestURL = "https://httpbin.org/post"; 15 const [getData, setResponse] = useState({ form: { item: "" } }); 16 17 const onSubmit = (data: any) => { 18 axios.post(requestURL, new URLSearchParams({ item: selectedItem })).then((response) => { 19 setResponse(response.data); 20 }); 21 }; 22 const handleChange = (e: any) => { 23 setItem(e.target.value); 24 }; 25 26 return ( 27 <div className="App"> 28 <h1>Form ImageRadio</h1> 29 <form onSubmit={handleSubmit(onSubmit)}> 30 <div> 31 </div> 32 {items.map((item) => { 33 return ( 34 <div key={item}> 35 <input 36 className={ImageRadioCss["item-input"]} 37 id={item} 38 type="radio" 39 {...register('item')} 40 value={item} 41 onChange={handleChange} 42 checked={item === selectedItem} 43 /> 44 <label 45 htmlFor={item} 46 47 className={ImageRadioCss[item]} 48 > 49 </label> 50 </div> 51 ); 52 })} 53 <button type="submit">Submit</button> 54 </form> 55 <div> 56 <h2>Item</h2> 57 <p>{getData['form']['item']}</p> 58 </div> 59 </div> 60 61 ); 62} 63 64export default ImageRadio;

Css module

css

1 2/* item1 / item2 のプロパティは共通化してない */ 3.item1 { 4 content: ""; 5 display: inline-block; 6 background-size: contain; 7 width: 100px; 8 height: 60px; 9 background-image: url(./images/1.png); 10} 11 12.item2 { 13 content: ""; 14 display: inline-block; 15 background-size: contain; 16 width: 100px; 17 height: 60px; 18 background-image: url(./images/2.png); 19} 20 21.item-input:checked + label { 22 border: 5px solid red; 23 box-sizing: border-box; 24} 25.item-input { 26 display:none; 27} 28 29

投稿2023/01/09 07:20

yuma.inaura

総合スコア1453

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Chihiro

2023/01/09 10:07

ありがとうございます。いただいた内容を参考にして試してみます。 取り急ぎ、お礼のお返事まで。
Chihiro

2023/01/14 04:34

yuma.inaura様、 きちんとしたお返事が遅れてしまいまして、申し訳ございません。 いただいた回答を参考に試してみたところ、ラジオボタン非表示でフォームの実装ができました。 おそらく、Controllerを使用していたせいかもしれません。 コードがかなり冗長的になってしまいましたが、Controllerを使用せず各セクションごとにregisterを使用したことでできました。 改めまして、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問