🖥

React で画像を選択するradio box のフォームを作ってaxiosでPOSTリクエストする

2023/09/01に公開

コード例

radioで選んだ値をuseStateの値として保持しておいて、axios通信時に利用している
CSSだけでやりくりするのが難しかったため

ImageRadio.tsx

import axios from "axios";
import ImageRadioCss from "./ImageRadio.module.css";

import { useForm } from "react-hook-form";
import { useState } from 'react'

const Form = () => {
  const { register, handleSubmit } = useForm();

  const items = ["item1", "item2"]
  const [selectedItem, setItem] = useState("");

  const requestURL = "https://httpbin.org/post";
  const [getData, setResponse] = useState({ form: { item: "" } });

  const onSubmit = (data: any) => {
    axios.post(requestURL, new URLSearchParams({ item: selectedItem })).then((response) => {
      setResponse(response.data);
    });
  };
  const handleChange = (e: any) => {
    setItem(e.target.value);
  };

  return (
    <div className="App">
      <h1>Form ImageRadio</h1>
      <form onSubmit={handleSubmit(onSubmit)}>
        <div>
        </div>
        {items.map((item) => {
          return (
            <div key={item}>
              <input
                className={ImageRadioCss["item-input"]}
                id={item}
                type="radio"
                {...register('item')}
                value={item}
                onChange={handleChange}
                checked={item === selectedItem}
              />
              <label
                htmlFor={item}

                className={ImageRadioCss[item]}
              >
              </label>
            </div>
          );
        })}
        <button type="submit">Submit</button>
      </form>
      <div>
        <h2>Item</h2>
        <p>{getData['form']['item']}</p>
      </div>
    </div>

  );
}

export default Form;

ImageRadio.module.css


/* item1 / item2 のプロパティは共通化してない */
.item1 {
  content: "";
  display: inline-block;
  background-size: contain;
  width: 100px;
  height: 60px;
  background-image: url(./images/1.png);
}

.item2 {
  content: "";
  display: inline-block;
  background-size: contain;
  width: 100px;
  height: 60px;
  background-image: url(./images/2.png);
}

.item-input:checked + label {
  border: 5px solid red;
  box-sizing: border-box;
}
.item-input {
  display:none;
}

動作例

<img width="1374" alt="image" src="https://user-images.githubusercontent.com/13635059/211257325-b88c6fc0-83c4-4473-813f-0cc9122ab45d.png">

環境

next@13.1.1

チャットメンバー募集

何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ

Twitter

https://twitter.com/YumaInaura

公開日時

2023-01-09

Discussion