0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

今日の学び(React数値入力・ボタン実装Tipsまとめ)

Posted at
# React コンポーネント実装メモ(数値入力、ボタン、SelectBox、map、propsの流れ)

## 1. 数量の増減UIの実装パターン

```tsx
const minQuantity = 1
const maxQuantity = 99
const [quantity, setQuantity] = useState<string | number>('')

<div className={styles.quantityRow}>
  <Button
    name="-"
    handleClick={() => {
      setQuantity(q => {
        const num = typeof q === 'number' ? q : parseInt(q as string, 10) || minQuantity
        return num > minQuantity ? num - 1 : minQuantity
      })
    }}
  />
  <Input
    id="quantity"
    type="number"
    value={quantity === '' ? '' : String(quantity)}
    onChange={e => {
      const value = e.target.value
      if (value === '') {
        setQuantity('')
      } else {
        const num = parseInt(value, 10)
        if (!isNaN(num) && num >= minQuantity && num <= maxQuantity) {
          setQuantity(value)
        }
      }
    }}
    placeholder="数量"
    name="quantity"
    maxLength={2}
    width="12rem"
  />
  <Button
    name="+"
    handleClick={() => {
      setQuantity(q => {
        const num = typeof q === 'number' ? q : parseInt(q as string, 10) || minQuantity
        return num < maxQuantity ? num + 1 : maxQuantity
      })
    }}
  />
</div>

2. 配列+mapでボタンをまとめて表示

const buttonList = [
  { label: '今すぐに買う', className: styles.buyNow },
  { label: 'カートに入れる', className: styles.addCart },
  { label: 'カートへ', className: styles.gotoCart },
]

<div>
  {buttonList.map(btn => (
    <button
      key={btn.label}
      className={`${styles.button} ${btn.className}`}
    >
      {btn.label}
    </button>
  ))}
</div>

3. SelectBoxのstate管理の理由

  • 親コンポーネントで選択状態(selectedCategoryなど)をuseStateで管理することで、他の処理や表示と連動可能。
  • 子コンポーネント(SelectBox)内部だけでstate管理すると、外部から値の取得や連携ができなくなるため注意。

4. inputのvalue型はstringにする理由

  • Reactのinputはvalueをstring型で管理するのが原則。
  • 数値を管理したい場合でも、value={quantity === '' ? '' : String(quantity)} のようにstringで渡すとエラーや警告を防げる。

5. 条件付きレンダリング(isEdit)

{isEdit ? (
  <SelectBox ... />
) : (
  <Label label={majorCategory} ... />
)}
  • 編集モードの時だけ編集UI(例:SelectBox)を表示。
  • それ以外はLabelなど通常表示。

6. useEffectでstate変化時のみログ出力

useEffect(() => {
  console.log("isEdit changed:", isEdit);
}, [isEdit]);
  • isEdit の変化だけをログに出したい場合に便利。

7. その他Tips

  • maxLengthはinputの最大入力文字数制限
  • nameはフォーム送信時やライブラリ利用時にkeyとして使われる
  • ||?演算子はJS標準の「論理和」や「optional chaining」

フロントエンド業務で役立つリアルな実装&Tipsをまとめました。

間違いや質問があればコメント歓迎です!


---

이대로 **Qiita에 바로 붙여넣으면** 됩니다!  
더 추가하거나, 특정 항목 더 자세히/간단히 하고 싶으면 말씀해 주세요!
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?