Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?
@SwuBHj8aKGqBKHet

久々reactでの個人的ハマったポイント備忘録

reactとreduxを一気に学習すると最初はわかったつもりでも
忘れたり、こんがらがったりすることがありました。
その中での備忘録です。

getElementByIdでオブジェクトが取れない

自分の場合はコンポーネントのライフサイクルを完全に忘れてしまっていました。
コンポーネントのライフサイクルをざっくり書くと

コンポーネントがマウントされて

再レンダーされて

アンマウントされる

というものです。

errorCompleteGet.jsx

const ButtonText = () => {
    const buttonName = document.getElementById("button").innerText;

    const getButtonName = () => {
        alert(buttonName)
    }

    return (
        <section>
            <button onClick={() => {getButtonName()}} id="button">ボタン</button>
        </section>
    )
}

getElementByIdの1行はreturnの前に実行されてしまうので例外が走って


TypeError: document.getElementById(...) is null

となってしまいます。
こうなるとreturnの後、つまりコンポーネントライフサイクルでいうと
マウントされた後に実行したいとなるわけですが
そこで最近であればuseEffect※1を使う場面となります。
※1react hooksの関数

CompleteGet.jsx

const ButtonText = () => {

    let buttonName = ""; //1

    const getButtonName = (buttonName) => {
        alert(buttonName) //4 クリックされた時点で実行。クリックされなければ実行されない
    }

    useEffect((event) => {
        buttonName = document.getElementById("button").innerText; //3
    },[]);

    return ( //2
        <section>
            <button onClick={() => {getButtonName(buttonName)}} id="button">ボタン</button>
        </section>
    )

}

useEffectの詳細は割愛させていただきますが
上記のようにuseEffectのコールバック関数で実行することで
コンポーネントマウント後にgetElementByIdが実行されるので
オブジェクトが取得できるようになります。
コメントアウトの番号は実行される順番になります。

無限ループが起こる

関数でコンポーネントを定義していてreturnの中でクリックイベントを発生させたい時。
具体的には以下のような形で書くと無限ループが発生するようになりました。

errorCounter.jsx

const CounterComponent = () => {

    let [count, counter] = useState(0);

    const countUp = () => {
        counter(count + 1);
    }

    return (
        <section>
            <button onClick={countUp}>カウント|{count}</button>
        </section>
    )
}

export default CounterComponent

以下エラーメッセージです。

error.console

Too many re-renders. React limits the number of renders to prevent an infinite loop.

ここでポイントとなるのが前述ソース内の

onClick.jsx

onClick={countUp}

この書き方だとcountUp関数はクリックしなくても最初コンポーネントマウント時に実行されてしまうんですね。
するとsetStateする関数であるcounterが走る
そうなるとstateが変化したので再レンダー処理が走る(上記ソース内でのreturn文)
つまり
countUp

counter(stateがセットされ再レンダーの合図)

return(再レンダー)

countUp


となりめでたく無限ループが完成します。
そこで対策として

okOnClick.jsx

onClick={() => {countUp}}

として即時関数でラップしてあげると
クリックされて初めてcountUpが実行されます。

所感

学習時は理屈がわかって、写経して動いても
実際自分で組み立てて使う時にハマり
わかってないところが浮き彫りになりますね。
1つ1つ丁寧に理解することも復習時には大事だと実感しました。

参考サイト

無限ループのところで参考にさせていただきました。ありがとうございます。

0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
SwuBHj8aKGqBKHet
webデザインから入って割と広くやる人です。2020年はreact+redux(hooks),fiirebaseを触っていた年でした。21年はpython(Django)、AWS、typescriptなどを深掘りしたいです。前向きな人たちと繋がり、共に成長したい。修正依頼歓迎&感謝します。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
0
Help us understand the problem. What is going on with this article?