1
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】onClickとonChangeの違い

1
Posted at

使用している教材

Reactに入門した人のためのもっとReactが楽しくなるステップアップコース完全版

Udemyの教材「Reactに入門した人のためのもっとReactが楽しくなるステップアップコース完全版」のセクション3を進めているときに、「表示」ボタンを押しても子コンポーネントが表示されないという問題がありました。

原因は、button要素に使うべきイベントonClickを、間違えてonChangeと書いていたことでした。

この記事では、発生した問題と、その原因であるonClickとonChangeの違いについて解説をしたいと思います。

どんな問題が起きたか

作っていたのは、入力フォームに文字を入力し、「表示」ボタンを押すと、その下に「子コンポーネント」が表示されるというシンプルな機能です。

2Wz5c3dCsm.png

しかし、表示ボタンを押しても何も反応がない状態でした。

問題のあったコード

実際のコードです。親コンポーネント(App.tsx)が、子コンポーネント(ChildArea.tsx)の表示・非表示を管理しています。

ChildArea.tsx
export const ChildArea = (props: {open: boolean}) => {
const {open} = props;

  return (
    <>
    {open ? (    
    <div>   
    <p className="bg-blue-500">子コンポーネント</p>
    </div>
) : (null)}
    </>
  )
}

問題があった親コンポーネントのコードです。

App.tsx
import './App.css'
import { useState } from 'react'
import { ChildArea } from './ChildArea';

function App() {
  const [text, setText] = useState("");
  const [open, setOpen] = useState(false);

  const onTextChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setText(e.target.value);
  };

  const openTextChange = () => {
    setOpen(!open);
  };

  return (
    <>
      <div className="flex flex-col gap-6">
        <div>
          <input 
          value={text} 
          onChange ={onTextChange} 
          type="text" 
          className="border border-gray-300 rounded-md">
          </input>
          </div>
        <div>
          <button 
          onChange={openTextChange}  //buttonにonChangeを使っていた
          className="rounded-md text-blue-600">
          表示
          </button>
        </div>
        <div>
          <ChildArea open={open}/>
        </div>
      </div>
    </>
  )
}

export default App

原因

button要素はクリックして使うもので、値を変更するという概念がないため、onChangeイベントが発火しなかったのが原因です。

onClickとonChangeの違い

onChange
onChangeイベントは、フォーム要素の値が変更したときに発火するイベントです。
今回のコードでは、入力フォーム(input要素)に文字を入力する度にonTextChangeの関数が呼ばれ、textのstateが更新されます。

onClick
onClickイベントは、要素がクリックされた時に発火するイベントです。
など、ユーザーが直接押したりクリックしたりという操作を行う要素に対して使います。

今回は、表示ボタンを押した時に、子コンポーネントを表示・非表示するという機能を作りたかったので、button要素には、onClickイベントを設定するのが適していました。

修正後のコード

onChangeイベントを、onClickイベントに変更します。

App.tsx
import './App.css'
import { useState } from 'react'
import { ChildArea } from './ChildArea';

function App() {
  const [text, setText] = useState("");
  const [open, setOpen] = useState(false);

  const onTextChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setText(e.target.value);
  };

  const openTextChange = () => {
    setOpen(!open);
  };

  return (
    <>
      <div className="flex flex-col gap-6">
        <div>
          <input 
          value={text} 
          onChange ={onTextChange} 
          type="text" 
          className="border border-gray-300 rounded-md">
          </input>
          </div>
        <div>
          <button 
          onClick={openTextChange}  //onClickに修正する
          className="rounded-md text-blue-600">
          表示
          </button>
        </div>
        <div>
          <ChildArea open={open}/>
        </div>
      </div>
    </>
  )
}

export default App![AI8jsiYvxF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777480/df30d48d-320b-431f-aa15-b90606a2bca9.png)

この修正により、表示ボタンをクリックすることでopenTextChange関数が実行されて、openのstateがtrue/falseで切り替わり、子コンポーネントが正しく表示・非表示されるようになりました。

AI8jsiYvxF.png

1
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
1
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?