tofu5856
@tofu5856 (康矢 松村)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

ReactでIntersectionOfServerを実行する

やりたいこととできないこと
IntersectionOfServerの機能を反映させたいのですが
上手く機能致しません。

何が原因だと思うのか
cbを無名関数として実行しているのですが、console.logで調べてみた結果
cbが取れていなく、それが原因だと思います。
原因としてはcbを関数として実行していないからだと思われます。
しかし自分の勉強不足で、cbを実行させる方法がわからないので
是非ご教授いただければ幸いです。
useEffectでのchildは取得できておりました。

参考
IntersectionOfServerについてはこちらから確認の方お願いします。
https://developer.mozilla.org/ja/docs/Web/API/Intersection_Observer_API

import React, { useRef, useEffect, useState } from "react";
import App from "../../App";

export const Intersection = ({ children }) => {
  // childrenから子要素を参照する

  // コンポーネントがマウントした後、渡した関数を実行する
  useEffect(() => {
    const child = document.querySelector("#test");
    console.log(child);

    // debugger; /* -- 一応コメントアウトしておきます -- */

    if (child) {
      /* ここにIntersectionObserverなどの処理 */

      const cb = function (entries, observer) {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            entry.target.classList.add("inview");
            // observer.unobserve(entry.target);
            alert("inview"); //機能しません
          } else {
            entry.target.classList.remove("inview");
          }
          const options = {
            root: null,
            rootMargin: "-300px 0px",
            threshold: [0, 0.5, 1],
          };

          const io = new IntersectionObserver(cb, options);
          console.log(io); //ioが取れていない

          io.observe(child);
        });
      };
    }
  }, []); // 第二引数に空配列を渡す!

  return <div>{children /* childrenを使うように修正 */}</div>;
};

export default Intersection;

0

1Answer

まず、 cb に代入した無名関数は使われていません。どこかで cb() として呼び出してやる必要があります。以下の例を見てください。

// これは無名関数を作るだけで中身は実行されない
const cb = function() {
  console.log('hello');
};

cb(); // ここで初めて hello と出力

次に、 cb の中で IntersectionObserver を作っているのは順番がおかしいです。 new IntersectionObserver(cb, options) に渡す cb はコールバック関数、つまり「IntersectionObserverが、監視中のオブジェクトの交差を検出するたびに呼び出す処理」を含んだ関数です。監視されているオブジェクトが交差したら監視を始める、ということになり意味が通りません。正しくは以下のようにします。

// 交差を検出するたびに実行する処理を作る
const cb = function(entries, observer) {
  // ここは検出のたびに実行される
  entries.forEach((entry) => { ... });
};

// cb を渡して IntersectionObserver を作る
const options = { ... };
const observer = new IntersectionObserver(cb, options);

// 監視を始める
observer.observe(child);

// 以降、 observer は交差を検出したら cb() を呼ぶ
1Like

Comments

  1. @tofu5856

    Questioner

    とてもご丁寧な対応ありがとうございます!!
    何点かお聞き致したいことがあるので、ご対応の方何卒よろしくお願いします。
    まず、@uasi様からいただいたコードと自分のコードを見比べた結果、
    変更点は、options関数をcb関数から出すだけでよろしいでしょうか?
    IntersectionObserver(cb, options)周囲のコードの書き方に変更点がないように
    思われますがこれでよろしいでしょうか?
    お時間がある時にご返事がもらえれば幸いです。
  2. もう一度コードをよく見比べてみてください。 cb 関数から出すのは options だけではありません。元のコードでいうと

    const options = {
    root: null,
    rootMargin: "-300px 0px",
    threshold: [0, 0.5, 1],
    };

    const io = new IntersectionObserver(cb, options);
    console.log(io); //ioが取れていない

    io.observe(child);

    この部分すべてを cb の外に出してください。

    コードの見た目だけを追うのではなく、何の処理をしているか1行ずつイメージしてみるといいですよ。 「IntersectionObserver を作って cb という処理をさせる」がやりたいのに、 cb の中で初めて IntersectionObserver を作るのはなんだか変だぞ、と思えるようになればデバッグが早くなります。
  3. 周囲のコードはこれでよさそうです。

Your answer might help someone💌