JSFiddle - React, Tailwind, and code Playground

HTML

<header><div>menu1</div><div>menu2</div></header>

<section class="Gray">
  <div>contentsGray</div>
</section>

<section class="Red">
  <div>contentsRed</div>
</section>

<section class="Blue">
  <div>contentsBlue</div>
</section>

CSS

body {
    background: #fff;
    padding: 0;
    margin: 0;
}
section {
    height: calc(100vh - 50px);
    padding: 50px 0 0 0;
    background: gray;
}
section.Red.is_view{
    background: red;
}
section.Blue.is_view{
    background: blue;
}
header {
    display: flex;
    align-items: center;
    justify-content: space-evenly;    
    position: fixed;
    top: 0; right: 0; left: 0;
    height: 50px;
    background: black;
    color: white;
}

JavaScript

const opts = {
  root: null, // 任意のHTML*Elementを指定して表示領域を設定できる
  rootMargin: '50px 0px 0px 0px', // viewport(root)のマージン指定例
  // 監視対象の交差率でイベント発火回数を指定
  // 未表示 <--                --> 表示しきった(解釈が微妙ですが)
  threshold: [0, 0.25, 0.75, 1]
};
let iObserver = new IntersectionObserver((entries) => {
  // entries is {Array.<IntersectionObserverEntry>}
  entries.forEach( (entry, idx) => {
    /*
    console.log({
      entryNumber: idx,
      isIntersecting: entry.isIntersecting,
      intersectionRatio: entry.intersectionRatio,
      rootBounds: JSON.stringify(entry.rootBounds),
      boundingClientRect: JSON.stringify(entry.boundingClientRect),
      intersectionRect: JSON.stringify(entry.intersectionRect )
    });
    */
    let elm = entry.target;
    // 指定した threshold と比較できる プロパティが intersectionRatio の様子
    /*
    if( entry.intersectionRatio < 0.25 || 0.75 < entry.intersectionRatio ) {
      elm.classList.remove("is_view");
      console.log(elm.className + 'を脱色');
      return;
    }
    */

    if( entry.isIntersecting ){
      console.log(elm.className + 'を着色');
      elm.classList.add('is_view');
    }
  });

}, opts);
// 監視対象要素を登録
//iObserver.observe( document.querySelector(".Gray") );
iObserver.observe( document.querySelector(".Red") );
//iObserver.observe( document.querySelector(".Blue") );