okashi
@okashi (oyatsu daisuki)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Reactのrefがどう動いているのかがわからない

Q&A

Closed

ReactもMapboxも初心者です。
React と Mapbox GL JS を使ってベクトルタイルを表示する
という記事を読んで、refの動きがわからなかったため質問させていただきます。

この記事には下記のような説明があります。
- Mapbox GL JS の Map クラスのインスタンス化の際に HTML エレメントを指定する必要がある
- React コンポーネントの中でHTMLエレメントを取得するには ref props を使う。
ポイントは、コンポーネントのマウントが完了し、 DOM が出来上がっている componentDidMount 以降のライフサイクルでインスタンス化を行う

と説明してあり、下記のコードでちゃんと動くのですが、自分にはよくわからないのが

わからない部分.js
render() {
  return <div className={'map'} ref={e => (this.container = e)} />
}

の部分の、ref={e => (this.container = e)} です。
イベントが発動したら、このAppクラスのインスタンスのcontainerにイベントが伝えられる?
この場合のイベントは何なのか、すでに画面が表示されているので
htmlにすでに window openみたいなイベントが発動して mapboxが背景地図は勝手に表示しているのか?


// src/App.js
import React, { Component } from 'react'
import mapboxgl from 'mapbox-gl'
import './App.css'
import 'mapbox-gl/dist/mapbox-gl.css'

class App extends Component {

  componentDidMount() {
    this.map = new mapboxgl.Map({
      container: this.container,
      style: 'mapbox://styles/mapbox/streets-v9',/* Mapbox 独自のスキームが指定されている */
    })
  }

  componentWillUnmount() {
    this.map.remove()
  }

  render() {
    return <div className={'map'} ref={e => (this.container = e)} />
  }
}

export default App

0

1Answer

Reactコンポーネントのライフサイクルは以下のようになっています。
https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

つまり、

  1. render
  2. componentDidMount
    の順番で呼ばれることになります。

renderが実行されるとき、関数e => (this.container = e)が実行され、
Appコンポーネントのインスタンスにcontainerフィールドがセットされます。
this.containerはdivエレメントを指していることになります。

次にcomponentDidMountが呼ばれると、mapboxgl.Mapのインスタンスを生成します。このとき
先ほどthis.containerにセットされたdivエレメントを渡します。Mapはこのdivを基準にして自身のエレメントの作成と描画を行います。

このref={e => (this.container = e)}って書き方はコールバック Ref と言います。

ここまで書いてなんですが、私はReact使ったことないです。

4Like

Comments

  1. @okashi

    Questioner

    @chromia さん、回答ありがとうございます!
    コールバック Ref ! そのページは途中で力尽きて読んでいなかったので、今週の休みによく読んでみようと思います。

    > ここまで書いてなんですが、私はReact使ったことないです。

    JSを理解していればある程度Reactもわかるということですよね、
    私は Javascriptもかなり未熟なので、同時に勉強しないといけない感じになっています。

Your answer might help someone💌